<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>flutter 入门指南 | AJ</title>
    <meta name="generator" content="VuePress 1.5.0">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    <script>
            var _hmt = _hmt || [];
            (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?51b8c2e72d1adf96524638ce85bb7d72";
            var s = document.getElementsByTagName("script")[0]; 
            s.parentNode.insertBefore(hm, s);

            // 引入谷歌,不需要可删除这段
            var hm1 = document.createElement("script");
            hm1.src = "https://www.googletagmanager.com/gtag/js?id=G-B7351EYS04";
            var s1 = document.getElementsByTagName("script")[0]; 
            s1.parentNode.insertBefore(hm1, s1);
            })();

            // 谷歌加载,不需要可删除
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());

            gtag('config', 'G-B7351EYS04');
        </script>
    <meta name="description" content="阿俊博客|记录一个程序员的成长历程 阿俊博客(blog.zhequtao.com)记录一个后端程序员的成长历程,分享他的学习笔记和心得,还有些开发必备技巧哦! java golang web html dev开发">
    <link rel="preload" href="/assets/css/0.styles.a3df589e.css" as="style"><link rel="preload" href="/assets/js/app.cb35c8f6.js" as="script"><link rel="preload" href="/assets/js/2.063846a6.js" as="script"><link rel="preload" href="/assets/js/4.1ffb4609.js" as="script"><link rel="preload" href="/assets/js/698.200cc84f.js" as="script"><link rel="prefetch" href="/assets/js/10.5629fe4d.js"><link rel="prefetch" href="/assets/js/100.8417ccea.js"><link rel="prefetch" href="/assets/js/101.37fdb377.js"><link rel="prefetch" href="/assets/js/102.848b686d.js"><link rel="prefetch" href="/assets/js/103.6a2489a0.js"><link rel="prefetch" href="/assets/js/104.99e8899f.js"><link rel="prefetch" href="/assets/js/105.8b741763.js"><link rel="prefetch" href="/assets/js/106.08163715.js"><link rel="prefetch" href="/assets/js/107.21801349.js"><link rel="prefetch" href="/assets/js/108.e3a2892b.js"><link rel="prefetch" href="/assets/js/109.dab5618c.js"><link rel="prefetch" href="/assets/js/11.cddc1623.js"><link rel="prefetch" href="/assets/js/110.f5249b39.js"><link rel="prefetch" href="/assets/js/111.9abf8bce.js"><link rel="prefetch" href="/assets/js/112.8eb86924.js"><link rel="prefetch" href="/assets/js/113.c180ed46.js"><link rel="prefetch" href="/assets/js/114.2370f5b5.js"><link rel="prefetch" href="/assets/js/115.88dc3fd8.js"><link rel="prefetch" href="/assets/js/116.63403600.js"><link rel="prefetch" href="/assets/js/117.83674aa0.js"><link rel="prefetch" href="/assets/js/118.9c58c685.js"><link rel="prefetch" href="/assets/js/119.621f9a70.js"><link rel="prefetch" href="/assets/js/12.ff3d03f5.js"><link rel="prefetch" href="/assets/js/120.a6d2b7f7.js"><link rel="prefetch" href="/assets/js/121.ae0ce9d1.js"><link rel="prefetch" href="/assets/js/122.de240e6d.js"><link rel="prefetch" href="/assets/js/123.b043e3e4.js"><link rel="prefetch" href="/assets/js/124.550af937.js"><link rel="prefetch" href="/assets/js/125.6f06b34c.js"><link rel="prefetch" href="/assets/js/126.38d64604.js"><link rel="prefetch" href="/assets/js/127.a948db56.js"><link rel="prefetch" href="/assets/js/128.4ca789e0.js"><link rel="prefetch" href="/assets/js/129.59be4505.js"><link rel="prefetch" href="/assets/js/13.e9f75cc3.js"><link rel="prefetch" href="/assets/js/130.ddae76a9.js"><link rel="prefetch" href="/assets/js/131.d969c265.js"><link rel="prefetch" href="/assets/js/132.5f43ce5c.js"><link rel="prefetch" href="/assets/js/133.b651af22.js"><link rel="prefetch" href="/assets/js/134.2499236a.js"><link rel="prefetch" href="/assets/js/135.4180596c.js"><link rel="prefetch" href="/assets/js/136.2c309233.js"><link rel="prefetch" href="/assets/js/137.72ca42dd.js"><link rel="prefetch" href="/assets/js/138.3772cd38.js"><link rel="prefetch" href="/assets/js/139.1d0a53da.js"><link rel="prefetch" href="/assets/js/14.be4b89ed.js"><link rel="prefetch" href="/assets/js/140.22368353.js"><link rel="prefetch" href="/assets/js/141.a14aef3c.js"><link rel="prefetch" href="/assets/js/142.2041ce3a.js"><link rel="prefetch" href="/assets/js/143.377262ec.js"><link rel="prefetch" href="/assets/js/144.8fcbc368.js"><link rel="prefetch" href="/assets/js/145.46da36bf.js"><link rel="prefetch" href="/assets/js/146.eceae0d9.js"><link rel="prefetch" href="/assets/js/147.e1bd6531.js"><link rel="prefetch" href="/assets/js/148.76f193ce.js"><link rel="prefetch" href="/assets/js/149.587bd581.js"><link rel="prefetch" href="/assets/js/15.e3219ac0.js"><link rel="prefetch" href="/assets/js/150.169c71e0.js"><link rel="prefetch" href="/assets/js/151.384021ea.js"><link rel="prefetch" href="/assets/js/152.0f20cf03.js"><link rel="prefetch" href="/assets/js/153.fd94af1e.js"><link rel="prefetch" href="/assets/js/154.a550f5dc.js"><link rel="prefetch" href="/assets/js/155.ba1ae86e.js"><link rel="prefetch" href="/assets/js/156.3b98ded0.js"><link rel="prefetch" href="/assets/js/157.cd378596.js"><link rel="prefetch" href="/assets/js/158.c138d0df.js"><link rel="prefetch" href="/assets/js/159.2635f7f4.js"><link rel="prefetch" href="/assets/js/16.c9c35d42.js"><link rel="prefetch" href="/assets/js/160.d51b4126.js"><link rel="prefetch" href="/assets/js/161.5dc29e7b.js"><link rel="prefetch" href="/assets/js/162.f257a92b.js"><link rel="prefetch" href="/assets/js/163.9eb75e40.js"><link rel="prefetch" href="/assets/js/164.8fb1e22b.js"><link rel="prefetch" href="/assets/js/165.49255503.js"><link rel="prefetch" href="/assets/js/166.e54539e6.js"><link rel="prefetch" href="/assets/js/167.a06acdb0.js"><link rel="prefetch" href="/assets/js/168.948ab620.js"><link rel="prefetch" href="/assets/js/169.7d756812.js"><link rel="prefetch" href="/assets/js/17.81067bc8.js"><link rel="prefetch" href="/assets/js/170.ffe63330.js"><link rel="prefetch" href="/assets/js/171.835398b9.js"><link rel="prefetch" href="/assets/js/172.3987be39.js"><link rel="prefetch" href="/assets/js/173.e3cedb8a.js"><link rel="prefetch" href="/assets/js/174.11a32588.js"><link rel="prefetch" href="/assets/js/175.da6f9782.js"><link rel="prefetch" href="/assets/js/176.50e55edc.js"><link rel="prefetch" href="/assets/js/177.a89a1d17.js"><link rel="prefetch" href="/assets/js/178.7ad3ce84.js"><link rel="prefetch" href="/assets/js/179.98a1343b.js"><link rel="prefetch" href="/assets/js/18.b67caf4c.js"><link rel="prefetch" href="/assets/js/180.4e98599b.js"><link rel="prefetch" href="/assets/js/181.dd885afd.js"><link rel="prefetch" href="/assets/js/182.789990c8.js"><link rel="prefetch" href="/assets/js/183.f11ca2fd.js"><link rel="prefetch" href="/assets/js/184.fcf128ec.js"><link rel="prefetch" href="/assets/js/185.54e1e9b6.js"><link rel="prefetch" href="/assets/js/186.db91021a.js"><link rel="prefetch" href="/assets/js/187.5309dd42.js"><link rel="prefetch" href="/assets/js/188.615821ea.js"><link rel="prefetch" href="/assets/js/189.f23f1d42.js"><link rel="prefetch" href="/assets/js/19.294a011c.js"><link rel="prefetch" href="/assets/js/190.efe894bc.js"><link rel="prefetch" href="/assets/js/191.0d14904a.js"><link rel="prefetch" href="/assets/js/192.efd25a9e.js"><link rel="prefetch" href="/assets/js/193.88151f34.js"><link rel="prefetch" href="/assets/js/194.efedce14.js"><link rel="prefetch" href="/assets/js/195.03ac15bb.js"><link rel="prefetch" href="/assets/js/196.fbc18389.js"><link rel="prefetch" href="/assets/js/197.0257ab5e.js"><link rel="prefetch" href="/assets/js/198.f1de2817.js"><link rel="prefetch" href="/assets/js/199.8f1c166b.js"><link rel="prefetch" href="/assets/js/20.1a41edb1.js"><link rel="prefetch" href="/assets/js/200.4af99727.js"><link rel="prefetch" href="/assets/js/201.9f8caef1.js"><link rel="prefetch" href="/assets/js/202.6f07d705.js"><link rel="prefetch" href="/assets/js/203.5012fe50.js"><link rel="prefetch" href="/assets/js/204.3a0dfd8e.js"><link rel="prefetch" href="/assets/js/205.0ba9b606.js"><link rel="prefetch" href="/assets/js/206.663a49ec.js"><link rel="prefetch" href="/assets/js/207.b2406149.js"><link rel="prefetch" href="/assets/js/208.b0b2dfd8.js"><link rel="prefetch" href="/assets/js/209.41a0ec9f.js"><link rel="prefetch" href="/assets/js/21.b6ea6f9a.js"><link rel="prefetch" href="/assets/js/210.6f36beb8.js"><link rel="prefetch" href="/assets/js/211.90ef6e5c.js"><link rel="prefetch" href="/assets/js/212.42339063.js"><link rel="prefetch" href="/assets/js/213.a2bfeda9.js"><link rel="prefetch" href="/assets/js/214.5c7eb42a.js"><link rel="prefetch" href="/assets/js/215.18260ae5.js"><link rel="prefetch" href="/assets/js/216.7678fd29.js"><link rel="prefetch" href="/assets/js/217.9d936f88.js"><link rel="prefetch" href="/assets/js/218.bac403c4.js"><link rel="prefetch" href="/assets/js/219.9d8cb16b.js"><link rel="prefetch" href="/assets/js/22.367cc253.js"><link rel="prefetch" href="/assets/js/220.375b7707.js"><link rel="prefetch" href="/assets/js/221.3e400da4.js"><link rel="prefetch" href="/assets/js/222.8fbd2857.js"><link rel="prefetch" href="/assets/js/223.76a10075.js"><link rel="prefetch" href="/assets/js/224.ff94cc4e.js"><link rel="prefetch" href="/assets/js/225.d4688ca6.js"><link rel="prefetch" href="/assets/js/226.b13b18af.js"><link rel="prefetch" href="/assets/js/227.288d0f96.js"><link rel="prefetch" href="/assets/js/228.60430ac0.js"><link rel="prefetch" href="/assets/js/229.da728342.js"><link rel="prefetch" href="/assets/js/23.bc3de730.js"><link rel="prefetch" href="/assets/js/230.d8417d20.js"><link rel="prefetch" href="/assets/js/231.6a9ce0b4.js"><link rel="prefetch" href="/assets/js/232.7611b413.js"><link rel="prefetch" href="/assets/js/233.94712cf9.js"><link rel="prefetch" href="/assets/js/234.93888298.js"><link rel="prefetch" href="/assets/js/235.62506981.js"><link rel="prefetch" href="/assets/js/236.5a055c7c.js"><link rel="prefetch" href="/assets/js/237.0a6c4902.js"><link rel="prefetch" href="/assets/js/238.e5f37663.js"><link rel="prefetch" href="/assets/js/239.331bba86.js"><link rel="prefetch" href="/assets/js/24.82f0901c.js"><link rel="prefetch" href="/assets/js/240.59591cfc.js"><link rel="prefetch" href="/assets/js/241.ce671f47.js"><link rel="prefetch" href="/assets/js/242.fb2542fa.js"><link rel="prefetch" href="/assets/js/243.74abc73d.js"><link rel="prefetch" href="/assets/js/244.ecd707b2.js"><link rel="prefetch" href="/assets/js/245.d728367b.js"><link rel="prefetch" href="/assets/js/246.9270e7fe.js"><link rel="prefetch" href="/assets/js/247.a421ba15.js"><link rel="prefetch" href="/assets/js/248.e759132e.js"><link rel="prefetch" href="/assets/js/249.3077fb46.js"><link rel="prefetch" href="/assets/js/25.95c551dc.js"><link rel="prefetch" href="/assets/js/250.5fe4dd03.js"><link rel="prefetch" href="/assets/js/251.4b8fe76c.js"><link rel="prefetch" href="/assets/js/252.0d1cf7ea.js"><link rel="prefetch" href="/assets/js/253.89d16ba0.js"><link rel="prefetch" href="/assets/js/254.8d1afc68.js"><link rel="prefetch" href="/assets/js/255.64e680cb.js"><link rel="prefetch" href="/assets/js/256.9defbd0e.js"><link rel="prefetch" href="/assets/js/257.1fef24fd.js"><link rel="prefetch" href="/assets/js/258.4e205286.js"><link rel="prefetch" href="/assets/js/259.f3d56efc.js"><link rel="prefetch" href="/assets/js/26.7fe56bac.js"><link rel="prefetch" href="/assets/js/260.378299e6.js"><link rel="prefetch" href="/assets/js/261.8e4fb397.js"><link rel="prefetch" href="/assets/js/262.54595d98.js"><link rel="prefetch" href="/assets/js/263.fb333dc1.js"><link rel="prefetch" href="/assets/js/264.13d13301.js"><link rel="prefetch" href="/assets/js/265.c85104bc.js"><link rel="prefetch" href="/assets/js/266.9f3d1f1c.js"><link rel="prefetch" href="/assets/js/267.fb392815.js"><link rel="prefetch" href="/assets/js/268.add7eacb.js"><link rel="prefetch" href="/assets/js/269.7e49fcc7.js"><link rel="prefetch" href="/assets/js/27.5547e5f0.js"><link rel="prefetch" href="/assets/js/270.22342070.js"><link rel="prefetch" href="/assets/js/271.59917b1a.js"><link rel="prefetch" href="/assets/js/272.4a4751d5.js"><link rel="prefetch" href="/assets/js/273.f4c2fa5c.js"><link rel="prefetch" href="/assets/js/274.1208bc94.js"><link rel="prefetch" href="/assets/js/275.f6528753.js"><link rel="prefetch" href="/assets/js/276.a68772cd.js"><link rel="prefetch" href="/assets/js/277.f154ab32.js"><link rel="prefetch" href="/assets/js/278.bb616a63.js"><link rel="prefetch" href="/assets/js/279.6a356cff.js"><link rel="prefetch" href="/assets/js/28.b08b2847.js"><link rel="prefetch" href="/assets/js/280.5afc20fc.js"><link rel="prefetch" href="/assets/js/281.3cd86225.js"><link rel="prefetch" href="/assets/js/282.3ecb92aa.js"><link rel="prefetch" href="/assets/js/283.85159ea7.js"><link rel="prefetch" href="/assets/js/284.b6545c68.js"><link rel="prefetch" href="/assets/js/285.5e83ee29.js"><link rel="prefetch" href="/assets/js/286.2aad298d.js"><link rel="prefetch" href="/assets/js/287.3ca76244.js"><link rel="prefetch" href="/assets/js/288.5b17963d.js"><link rel="prefetch" href="/assets/js/289.f47a759b.js"><link rel="prefetch" href="/assets/js/29.562dbf7d.js"><link rel="prefetch" href="/assets/js/290.36b603c7.js"><link rel="prefetch" href="/assets/js/291.a9bd8951.js"><link rel="prefetch" href="/assets/js/292.dfc54f28.js"><link rel="prefetch" href="/assets/js/293.2d061212.js"><link rel="prefetch" href="/assets/js/294.6d564a9e.js"><link rel="prefetch" href="/assets/js/295.a31dd593.js"><link rel="prefetch" href="/assets/js/296.3101e5e8.js"><link rel="prefetch" href="/assets/js/297.7efde936.js"><link rel="prefetch" href="/assets/js/298.8bb3aa68.js"><link rel="prefetch" href="/assets/js/299.8b51e6bd.js"><link rel="prefetch" href="/assets/js/3.76257eb7.js"><link rel="prefetch" href="/assets/js/30.221adea2.js"><link rel="prefetch" href="/assets/js/300.62effe45.js"><link rel="prefetch" href="/assets/js/301.98c863c5.js"><link rel="prefetch" href="/assets/js/302.e3493ab2.js"><link rel="prefetch" href="/assets/js/303.800c8028.js"><link rel="prefetch" href="/assets/js/304.b6f08986.js"><link rel="prefetch" href="/assets/js/305.09af356b.js"><link rel="prefetch" href="/assets/js/306.d0d3589d.js"><link rel="prefetch" href="/assets/js/307.ee2fd249.js"><link rel="prefetch" href="/assets/js/308.f3f76368.js"><link rel="prefetch" href="/assets/js/309.d2b5ce40.js"><link rel="prefetch" href="/assets/js/31.334fc8bb.js"><link rel="prefetch" href="/assets/js/310.b4fa2feb.js"><link rel="prefetch" href="/assets/js/311.7d747ef3.js"><link rel="prefetch" href="/assets/js/312.89bdff40.js"><link rel="prefetch" href="/assets/js/313.875b82fe.js"><link rel="prefetch" href="/assets/js/314.0bbe51c4.js"><link rel="prefetch" href="/assets/js/315.cc07dbcf.js"><link rel="prefetch" href="/assets/js/316.bc72b152.js"><link rel="prefetch" href="/assets/js/317.55462812.js"><link rel="prefetch" href="/assets/js/318.a158fda0.js"><link rel="prefetch" href="/assets/js/319.b03a5bd2.js"><link rel="prefetch" href="/assets/js/32.d6826b16.js"><link rel="prefetch" href="/assets/js/320.a5bd19b0.js"><link rel="prefetch" href="/assets/js/321.4f9faaa7.js"><link rel="prefetch" href="/assets/js/322.dbd3b4fa.js"><link rel="prefetch" href="/assets/js/323.a04e2062.js"><link rel="prefetch" href="/assets/js/324.c45b46cf.js"><link rel="prefetch" href="/assets/js/325.cd1460c4.js"><link rel="prefetch" href="/assets/js/326.bd90ef85.js"><link rel="prefetch" href="/assets/js/327.8bf38ef7.js"><link rel="prefetch" href="/assets/js/328.99e9aed3.js"><link rel="prefetch" href="/assets/js/329.de0012cb.js"><link rel="prefetch" href="/assets/js/33.b1059062.js"><link rel="prefetch" href="/assets/js/330.59f11391.js"><link rel="prefetch" href="/assets/js/331.6d16a13c.js"><link rel="prefetch" href="/assets/js/332.922ca235.js"><link rel="prefetch" href="/assets/js/333.c94c3602.js"><link rel="prefetch" href="/assets/js/334.77e02010.js"><link rel="prefetch" href="/assets/js/335.1e0c4f7b.js"><link rel="prefetch" href="/assets/js/336.5675dc4f.js"><link rel="prefetch" href="/assets/js/337.bb6e11dc.js"><link rel="prefetch" href="/assets/js/338.294981e9.js"><link rel="prefetch" href="/assets/js/339.d0376372.js"><link rel="prefetch" href="/assets/js/34.0c7d5782.js"><link rel="prefetch" href="/assets/js/340.64596428.js"><link rel="prefetch" href="/assets/js/341.ec0f9409.js"><link rel="prefetch" href="/assets/js/342.7abc47c4.js"><link rel="prefetch" href="/assets/js/343.4262d486.js"><link rel="prefetch" href="/assets/js/344.8729ad8c.js"><link rel="prefetch" href="/assets/js/345.c210d888.js"><link rel="prefetch" href="/assets/js/346.6f42f7cb.js"><link rel="prefetch" href="/assets/js/347.81b41ae5.js"><link rel="prefetch" href="/assets/js/348.07eca37c.js"><link rel="prefetch" href="/assets/js/349.8019d6f3.js"><link rel="prefetch" href="/assets/js/35.ae14e37f.js"><link rel="prefetch" href="/assets/js/350.57da2e7b.js"><link rel="prefetch" href="/assets/js/351.2e99afdf.js"><link rel="prefetch" href="/assets/js/352.67dd88b7.js"><link rel="prefetch" href="/assets/js/353.15b9f624.js"><link rel="prefetch" href="/assets/js/354.a63e8432.js"><link rel="prefetch" href="/assets/js/355.bbc16ee9.js"><link rel="prefetch" href="/assets/js/356.ff63d3bb.js"><link rel="prefetch" href="/assets/js/357.4fb2d941.js"><link rel="prefetch" href="/assets/js/358.55182977.js"><link rel="prefetch" href="/assets/js/359.265c3d26.js"><link rel="prefetch" href="/assets/js/36.b9ed4cf1.js"><link rel="prefetch" href="/assets/js/360.ced80eb3.js"><link rel="prefetch" href="/assets/js/361.afe6ba84.js"><link rel="prefetch" href="/assets/js/362.c2b62518.js"><link rel="prefetch" href="/assets/js/363.0c4a4800.js"><link rel="prefetch" href="/assets/js/364.ce60291b.js"><link rel="prefetch" href="/assets/js/365.0e3a61f9.js"><link rel="prefetch" href="/assets/js/366.d53ccb03.js"><link rel="prefetch" href="/assets/js/367.689e464d.js"><link rel="prefetch" href="/assets/js/368.418c571f.js"><link rel="prefetch" href="/assets/js/369.c2fff3c8.js"><link rel="prefetch" href="/assets/js/37.a021ac57.js"><link rel="prefetch" href="/assets/js/370.a932b958.js"><link rel="prefetch" href="/assets/js/371.7d153241.js"><link rel="prefetch" href="/assets/js/372.fb9878fa.js"><link rel="prefetch" href="/assets/js/373.85772e03.js"><link rel="prefetch" href="/assets/js/374.b4a8b1b6.js"><link rel="prefetch" href="/assets/js/375.32f70596.js"><link rel="prefetch" href="/assets/js/376.a16d79a8.js"><link rel="prefetch" href="/assets/js/377.c996b7e1.js"><link rel="prefetch" href="/assets/js/378.d37d15c7.js"><link rel="prefetch" href="/assets/js/379.b81ba7dd.js"><link rel="prefetch" href="/assets/js/38.89138658.js"><link rel="prefetch" href="/assets/js/380.524c9b31.js"><link rel="prefetch" href="/assets/js/381.7ebfd6db.js"><link rel="prefetch" href="/assets/js/382.29edda0f.js"><link rel="prefetch" href="/assets/js/383.9642a212.js"><link rel="prefetch" href="/assets/js/384.086e3b42.js"><link rel="prefetch" href="/assets/js/385.a9bb46a8.js"><link rel="prefetch" href="/assets/js/386.f2561a39.js"><link rel="prefetch" href="/assets/js/387.ba9b6aaa.js"><link rel="prefetch" href="/assets/js/388.e0ace495.js"><link rel="prefetch" href="/assets/js/389.ba8c09dd.js"><link rel="prefetch" href="/assets/js/39.04f331e3.js"><link rel="prefetch" href="/assets/js/390.de1bb48b.js"><link rel="prefetch" href="/assets/js/391.7cc6edeb.js"><link rel="prefetch" href="/assets/js/392.0493a6f7.js"><link rel="prefetch" href="/assets/js/393.ba2d3e62.js"><link rel="prefetch" href="/assets/js/394.b3aa9224.js"><link rel="prefetch" href="/assets/js/395.f4df3a60.js"><link rel="prefetch" href="/assets/js/396.09644790.js"><link rel="prefetch" href="/assets/js/397.76163964.js"><link rel="prefetch" href="/assets/js/398.377fd8fc.js"><link rel="prefetch" href="/assets/js/399.39059be5.js"><link rel="prefetch" href="/assets/js/40.a21abf05.js"><link rel="prefetch" href="/assets/js/400.559a547f.js"><link rel="prefetch" href="/assets/js/401.bc6d738c.js"><link rel="prefetch" href="/assets/js/402.c504ed7b.js"><link rel="prefetch" href="/assets/js/403.77a0af9c.js"><link rel="prefetch" href="/assets/js/404.0f408cc6.js"><link rel="prefetch" href="/assets/js/405.90b0bab6.js"><link rel="prefetch" href="/assets/js/406.01b11432.js"><link rel="prefetch" href="/assets/js/407.58991ce5.js"><link rel="prefetch" href="/assets/js/408.9806278e.js"><link rel="prefetch" href="/assets/js/409.8d9b4bb3.js"><link rel="prefetch" href="/assets/js/41.6bcfc592.js"><link rel="prefetch" href="/assets/js/410.02dee620.js"><link rel="prefetch" href="/assets/js/411.3d12d3a6.js"><link rel="prefetch" href="/assets/js/412.37a62624.js"><link rel="prefetch" href="/assets/js/413.bda7ca34.js"><link rel="prefetch" href="/assets/js/414.2abb6547.js"><link rel="prefetch" href="/assets/js/415.1d271923.js"><link rel="prefetch" href="/assets/js/416.d1b11dfe.js"><link rel="prefetch" href="/assets/js/417.fcbf07ff.js"><link rel="prefetch" href="/assets/js/418.524d40ba.js"><link rel="prefetch" href="/assets/js/419.f264e463.js"><link rel="prefetch" href="/assets/js/42.ec85a270.js"><link rel="prefetch" href="/assets/js/420.8b99e60d.js"><link rel="prefetch" href="/assets/js/421.c697d876.js"><link rel="prefetch" href="/assets/js/422.4af54ae0.js"><link rel="prefetch" href="/assets/js/423.b75f24ff.js"><link rel="prefetch" href="/assets/js/424.ea80054f.js"><link rel="prefetch" href="/assets/js/425.804b48b0.js"><link rel="prefetch" href="/assets/js/426.ffed8383.js"><link rel="prefetch" href="/assets/js/427.2040bd22.js"><link rel="prefetch" href="/assets/js/428.b878fb56.js"><link rel="prefetch" href="/assets/js/429.f81fd922.js"><link rel="prefetch" href="/assets/js/43.c174449d.js"><link rel="prefetch" href="/assets/js/430.16f328ab.js"><link rel="prefetch" href="/assets/js/431.56f11924.js"><link rel="prefetch" href="/assets/js/432.e4c77710.js"><link rel="prefetch" href="/assets/js/433.29acf14b.js"><link rel="prefetch" href="/assets/js/434.33ee22fc.js"><link rel="prefetch" href="/assets/js/435.516f7600.js"><link rel="prefetch" href="/assets/js/436.28ae526a.js"><link rel="prefetch" href="/assets/js/437.b9bac473.js"><link rel="prefetch" href="/assets/js/438.711bd934.js"><link rel="prefetch" href="/assets/js/439.fe5f28bd.js"><link rel="prefetch" href="/assets/js/44.8704338b.js"><link rel="prefetch" href="/assets/js/440.b2f48747.js"><link rel="prefetch" href="/assets/js/441.4862a724.js"><link rel="prefetch" href="/assets/js/442.751f8ae7.js"><link rel="prefetch" href="/assets/js/443.9998dbe9.js"><link rel="prefetch" href="/assets/js/444.23d3f688.js"><link rel="prefetch" href="/assets/js/445.72419f35.js"><link rel="prefetch" href="/assets/js/446.21e02b7b.js"><link rel="prefetch" href="/assets/js/447.6bd039e5.js"><link rel="prefetch" href="/assets/js/448.af29ff31.js"><link rel="prefetch" href="/assets/js/449.bbdca196.js"><link rel="prefetch" href="/assets/js/45.f8a2a3b3.js"><link rel="prefetch" href="/assets/js/450.32e470b8.js"><link rel="prefetch" href="/assets/js/451.f4c8ff6a.js"><link rel="prefetch" href="/assets/js/452.c0ec8943.js"><link rel="prefetch" href="/assets/js/453.5af475c6.js"><link rel="prefetch" href="/assets/js/454.567aa6c1.js"><link rel="prefetch" href="/assets/js/455.326072d1.js"><link rel="prefetch" href="/assets/js/456.64b88847.js"><link rel="prefetch" href="/assets/js/457.61c91559.js"><link rel="prefetch" href="/assets/js/458.4f4d43d6.js"><link rel="prefetch" href="/assets/js/459.a88891cb.js"><link rel="prefetch" href="/assets/js/46.90855a0f.js"><link rel="prefetch" href="/assets/js/460.fb9e15f6.js"><link rel="prefetch" href="/assets/js/461.998a4991.js"><link rel="prefetch" href="/assets/js/462.56ecfb03.js"><link rel="prefetch" href="/assets/js/463.582cd053.js"><link rel="prefetch" href="/assets/js/464.f12a0050.js"><link rel="prefetch" href="/assets/js/465.cc3b08a8.js"><link rel="prefetch" href="/assets/js/466.ea7e4ce2.js"><link rel="prefetch" href="/assets/js/467.58700d93.js"><link rel="prefetch" href="/assets/js/468.bb9998cd.js"><link rel="prefetch" href="/assets/js/469.232d261d.js"><link rel="prefetch" href="/assets/js/47.02516d33.js"><link rel="prefetch" href="/assets/js/470.90ab2be8.js"><link rel="prefetch" href="/assets/js/471.3652fec6.js"><link rel="prefetch" href="/assets/js/472.bc7517c9.js"><link rel="prefetch" href="/assets/js/473.27b7892f.js"><link rel="prefetch" href="/assets/js/474.0d488768.js"><link rel="prefetch" href="/assets/js/475.bc33cf17.js"><link rel="prefetch" href="/assets/js/476.76ce67eb.js"><link rel="prefetch" href="/assets/js/477.a20657f6.js"><link rel="prefetch" href="/assets/js/478.8905ef26.js"><link rel="prefetch" href="/assets/js/479.23ec3dc9.js"><link rel="prefetch" href="/assets/js/48.8d38983c.js"><link rel="prefetch" href="/assets/js/480.105bf58e.js"><link rel="prefetch" href="/assets/js/481.d62a3699.js"><link rel="prefetch" href="/assets/js/482.6cb10cdb.js"><link rel="prefetch" href="/assets/js/483.15b9ef53.js"><link rel="prefetch" href="/assets/js/484.794aff9c.js"><link rel="prefetch" href="/assets/js/485.3e6ef3cb.js"><link rel="prefetch" href="/assets/js/486.fc20eb22.js"><link rel="prefetch" href="/assets/js/487.2a4f7d47.js"><link rel="prefetch" href="/assets/js/488.24ba9af5.js"><link rel="prefetch" href="/assets/js/489.d451928e.js"><link rel="prefetch" href="/assets/js/49.bd70c59c.js"><link rel="prefetch" href="/assets/js/490.d83e4fc7.js"><link rel="prefetch" href="/assets/js/491.0210a738.js"><link rel="prefetch" href="/assets/js/492.3a69cd85.js"><link rel="prefetch" href="/assets/js/493.89d2920f.js"><link rel="prefetch" href="/assets/js/494.b7d1c15e.js"><link rel="prefetch" href="/assets/js/495.7ccfe17f.js"><link rel="prefetch" href="/assets/js/496.0d6c912a.js"><link rel="prefetch" href="/assets/js/497.087ca2c6.js"><link rel="prefetch" href="/assets/js/498.f2b3c894.js"><link rel="prefetch" href="/assets/js/499.e741f312.js"><link rel="prefetch" href="/assets/js/5.405f2620.js"><link rel="prefetch" href="/assets/js/50.9df07553.js"><link rel="prefetch" href="/assets/js/500.cb9babb9.js"><link rel="prefetch" href="/assets/js/501.63a859b6.js"><link rel="prefetch" href="/assets/js/502.f346b273.js"><link rel="prefetch" href="/assets/js/503.cdcd3de3.js"><link rel="prefetch" href="/assets/js/504.e83ec450.js"><link rel="prefetch" href="/assets/js/505.95f18293.js"><link rel="prefetch" href="/assets/js/506.02060a3c.js"><link rel="prefetch" href="/assets/js/507.859d6ae4.js"><link rel="prefetch" href="/assets/js/508.9724d886.js"><link rel="prefetch" href="/assets/js/509.e17dd53e.js"><link rel="prefetch" href="/assets/js/51.3dfc6350.js"><link rel="prefetch" href="/assets/js/510.ea0c942f.js"><link rel="prefetch" href="/assets/js/511.64a7f9a8.js"><link rel="prefetch" href="/assets/js/512.6cce418a.js"><link rel="prefetch" href="/assets/js/513.ea813fe8.js"><link rel="prefetch" href="/assets/js/514.10242470.js"><link rel="prefetch" href="/assets/js/515.5308bdf6.js"><link rel="prefetch" href="/assets/js/516.dfb113bc.js"><link rel="prefetch" href="/assets/js/517.96c71069.js"><link rel="prefetch" href="/assets/js/518.5594480e.js"><link rel="prefetch" href="/assets/js/519.91e848ae.js"><link rel="prefetch" href="/assets/js/52.dd230cd7.js"><link rel="prefetch" href="/assets/js/520.ebe69ce9.js"><link rel="prefetch" href="/assets/js/521.92b80342.js"><link rel="prefetch" href="/assets/js/522.6ce581ea.js"><link rel="prefetch" href="/assets/js/523.40b7f2f9.js"><link rel="prefetch" href="/assets/js/524.4ef256d3.js"><link rel="prefetch" href="/assets/js/525.19741e4a.js"><link rel="prefetch" href="/assets/js/526.e5de1675.js"><link rel="prefetch" href="/assets/js/527.9a79cd42.js"><link rel="prefetch" href="/assets/js/528.72732eb8.js"><link rel="prefetch" href="/assets/js/529.2ea03e45.js"><link rel="prefetch" href="/assets/js/53.a349c565.js"><link rel="prefetch" href="/assets/js/530.5d1103e7.js"><link rel="prefetch" href="/assets/js/531.82b032d6.js"><link rel="prefetch" href="/assets/js/532.12ee4beb.js"><link rel="prefetch" href="/assets/js/533.db9a90f7.js"><link rel="prefetch" href="/assets/js/534.fe139db4.js"><link rel="prefetch" href="/assets/js/535.056a6fbb.js"><link rel="prefetch" href="/assets/js/536.6bf85c15.js"><link rel="prefetch" href="/assets/js/537.6e2e1ccf.js"><link rel="prefetch" href="/assets/js/538.54eddb3b.js"><link rel="prefetch" href="/assets/js/539.6f00a207.js"><link rel="prefetch" href="/assets/js/54.e292b52f.js"><link rel="prefetch" href="/assets/js/540.9c956205.js"><link rel="prefetch" href="/assets/js/541.50f41228.js"><link rel="prefetch" href="/assets/js/542.a2b1879e.js"><link rel="prefetch" href="/assets/js/543.4e5e17c9.js"><link rel="prefetch" href="/assets/js/544.63d85227.js"><link rel="prefetch" href="/assets/js/545.c3923644.js"><link rel="prefetch" href="/assets/js/546.e64ad073.js"><link rel="prefetch" href="/assets/js/547.35a8752d.js"><link rel="prefetch" href="/assets/js/548.b62a1348.js"><link rel="prefetch" href="/assets/js/549.369e2ea0.js"><link rel="prefetch" href="/assets/js/55.21bb2983.js"><link rel="prefetch" href="/assets/js/550.b4632248.js"><link rel="prefetch" href="/assets/js/551.18f1879c.js"><link rel="prefetch" href="/assets/js/552.162e63cd.js"><link rel="prefetch" href="/assets/js/553.6998130e.js"><link rel="prefetch" href="/assets/js/554.89126c3d.js"><link rel="prefetch" href="/assets/js/555.a5f63b8a.js"><link rel="prefetch" href="/assets/js/556.35381cef.js"><link rel="prefetch" href="/assets/js/557.ceeecf52.js"><link rel="prefetch" href="/assets/js/558.253e6e4f.js"><link rel="prefetch" href="/assets/js/559.5cfbb773.js"><link rel="prefetch" href="/assets/js/56.5382d6b4.js"><link rel="prefetch" href="/assets/js/560.cca52f22.js"><link rel="prefetch" href="/assets/js/561.ea8d1141.js"><link rel="prefetch" href="/assets/js/562.c32e7b96.js"><link rel="prefetch" href="/assets/js/563.9bdd42e7.js"><link rel="prefetch" href="/assets/js/564.b3b87ec0.js"><link rel="prefetch" href="/assets/js/565.4be0d0f7.js"><link rel="prefetch" href="/assets/js/566.9f379d12.js"><link rel="prefetch" href="/assets/js/567.261e3181.js"><link rel="prefetch" href="/assets/js/568.4229e365.js"><link rel="prefetch" href="/assets/js/569.e662c167.js"><link rel="prefetch" href="/assets/js/57.8129f7e0.js"><link rel="prefetch" href="/assets/js/570.97ff6423.js"><link rel="prefetch" href="/assets/js/571.de1377cd.js"><link rel="prefetch" href="/assets/js/572.48b8400b.js"><link rel="prefetch" href="/assets/js/573.8251ebaf.js"><link rel="prefetch" href="/assets/js/574.ec3d6c1e.js"><link rel="prefetch" href="/assets/js/575.b0d429a1.js"><link rel="prefetch" href="/assets/js/576.98ce9170.js"><link rel="prefetch" href="/assets/js/577.85fc2017.js"><link rel="prefetch" href="/assets/js/578.1393ac7f.js"><link rel="prefetch" href="/assets/js/579.1340e178.js"><link rel="prefetch" href="/assets/js/58.85ac2740.js"><link rel="prefetch" href="/assets/js/580.a5979445.js"><link rel="prefetch" href="/assets/js/581.effdc269.js"><link rel="prefetch" href="/assets/js/582.13276063.js"><link rel="prefetch" href="/assets/js/583.357a2443.js"><link rel="prefetch" href="/assets/js/584.338ef731.js"><link rel="prefetch" href="/assets/js/585.87932741.js"><link rel="prefetch" href="/assets/js/586.b1d6e000.js"><link rel="prefetch" href="/assets/js/587.ed5b8377.js"><link rel="prefetch" href="/assets/js/588.16d2c418.js"><link rel="prefetch" href="/assets/js/589.c96fd7fa.js"><link rel="prefetch" href="/assets/js/59.0b225757.js"><link rel="prefetch" href="/assets/js/590.1a06b2a0.js"><link rel="prefetch" href="/assets/js/591.0efd886c.js"><link rel="prefetch" href="/assets/js/592.b22d0ef5.js"><link rel="prefetch" href="/assets/js/593.84ed6ebe.js"><link rel="prefetch" href="/assets/js/594.cd721b88.js"><link rel="prefetch" href="/assets/js/595.2400817a.js"><link rel="prefetch" href="/assets/js/596.f2c512d1.js"><link rel="prefetch" href="/assets/js/597.df10ec57.js"><link rel="prefetch" href="/assets/js/598.61ef6a7d.js"><link rel="prefetch" href="/assets/js/599.0bebb562.js"><link rel="prefetch" href="/assets/js/6.29d112b1.js"><link rel="prefetch" href="/assets/js/60.3bbab51d.js"><link rel="prefetch" href="/assets/js/600.1ea7596f.js"><link rel="prefetch" href="/assets/js/601.f2642bb3.js"><link rel="prefetch" href="/assets/js/602.400cc987.js"><link rel="prefetch" href="/assets/js/603.db77d173.js"><link rel="prefetch" href="/assets/js/604.0ffa30ae.js"><link rel="prefetch" href="/assets/js/605.32ca9607.js"><link rel="prefetch" href="/assets/js/606.8c1e5683.js"><link rel="prefetch" href="/assets/js/607.9c9463ef.js"><link rel="prefetch" href="/assets/js/608.d5efa77e.js"><link rel="prefetch" href="/assets/js/609.5bbffb7d.js"><link rel="prefetch" href="/assets/js/61.f7301486.js"><link rel="prefetch" href="/assets/js/610.5b0fc9da.js"><link rel="prefetch" href="/assets/js/611.bb8058c9.js"><link rel="prefetch" href="/assets/js/612.b0788f43.js"><link rel="prefetch" href="/assets/js/613.49511e65.js"><link rel="prefetch" href="/assets/js/614.fae3eacf.js"><link rel="prefetch" href="/assets/js/615.359e5899.js"><link rel="prefetch" href="/assets/js/616.905132f4.js"><link rel="prefetch" href="/assets/js/617.6c8c594e.js"><link rel="prefetch" href="/assets/js/618.6ac4f3ff.js"><link rel="prefetch" href="/assets/js/619.411a0c14.js"><link rel="prefetch" href="/assets/js/62.9aeede84.js"><link rel="prefetch" href="/assets/js/620.56155724.js"><link rel="prefetch" href="/assets/js/621.149d7933.js"><link rel="prefetch" href="/assets/js/622.f0c9bc08.js"><link rel="prefetch" href="/assets/js/623.e0989fbe.js"><link rel="prefetch" href="/assets/js/624.80b1f6a9.js"><link rel="prefetch" href="/assets/js/625.a0a392c4.js"><link rel="prefetch" href="/assets/js/626.56fd4e8a.js"><link rel="prefetch" href="/assets/js/627.264e7313.js"><link rel="prefetch" href="/assets/js/628.7a868b19.js"><link rel="prefetch" href="/assets/js/629.e7e15da1.js"><link rel="prefetch" href="/assets/js/63.4df55c8b.js"><link rel="prefetch" href="/assets/js/630.998c9b61.js"><link rel="prefetch" href="/assets/js/631.69aa049c.js"><link rel="prefetch" href="/assets/js/632.da3882c1.js"><link rel="prefetch" href="/assets/js/633.0d49adf0.js"><link rel="prefetch" href="/assets/js/634.f9984ede.js"><link rel="prefetch" href="/assets/js/635.f0439f65.js"><link rel="prefetch" href="/assets/js/636.54de4194.js"><link rel="prefetch" href="/assets/js/637.55d1c226.js"><link rel="prefetch" href="/assets/js/638.2a9a510f.js"><link rel="prefetch" href="/assets/js/639.8bec360e.js"><link rel="prefetch" href="/assets/js/64.7f3e5e81.js"><link rel="prefetch" href="/assets/js/640.30d7f96e.js"><link rel="prefetch" href="/assets/js/641.68100098.js"><link rel="prefetch" href="/assets/js/642.4b793817.js"><link rel="prefetch" href="/assets/js/643.d86a81ea.js"><link rel="prefetch" href="/assets/js/644.76327ea2.js"><link rel="prefetch" href="/assets/js/645.0ac6a923.js"><link rel="prefetch" href="/assets/js/646.cd92f728.js"><link rel="prefetch" href="/assets/js/647.f2c624e1.js"><link rel="prefetch" href="/assets/js/648.c8f3b955.js"><link rel="prefetch" href="/assets/js/649.6370753b.js"><link rel="prefetch" href="/assets/js/65.2beeae9b.js"><link rel="prefetch" href="/assets/js/650.afe31909.js"><link rel="prefetch" href="/assets/js/651.87971ec0.js"><link rel="prefetch" href="/assets/js/652.0adf10a6.js"><link rel="prefetch" href="/assets/js/653.1f655726.js"><link rel="prefetch" href="/assets/js/654.53e24c7c.js"><link rel="prefetch" href="/assets/js/655.c95a66ea.js"><link rel="prefetch" href="/assets/js/656.38b5a5ea.js"><link rel="prefetch" href="/assets/js/657.3167aa94.js"><link rel="prefetch" href="/assets/js/658.7c40ff62.js"><link rel="prefetch" href="/assets/js/659.5d2b9b54.js"><link rel="prefetch" href="/assets/js/66.44b214db.js"><link rel="prefetch" href="/assets/js/660.96a8da9e.js"><link rel="prefetch" href="/assets/js/661.4de3b6c1.js"><link rel="prefetch" href="/assets/js/662.7d9bf181.js"><link rel="prefetch" href="/assets/js/663.4ccaf40a.js"><link rel="prefetch" href="/assets/js/664.7ab4fa53.js"><link rel="prefetch" href="/assets/js/665.32245d26.js"><link rel="prefetch" href="/assets/js/666.e6617151.js"><link rel="prefetch" href="/assets/js/667.fb3b0547.js"><link rel="prefetch" href="/assets/js/668.3d1b2e36.js"><link rel="prefetch" href="/assets/js/669.b769905f.js"><link rel="prefetch" href="/assets/js/67.c31aaacf.js"><link rel="prefetch" href="/assets/js/670.88ed3af3.js"><link rel="prefetch" href="/assets/js/671.1aff6bfe.js"><link rel="prefetch" href="/assets/js/672.c90888f7.js"><link rel="prefetch" href="/assets/js/673.81241fdc.js"><link rel="prefetch" href="/assets/js/674.838a424d.js"><link rel="prefetch" href="/assets/js/675.603ac896.js"><link rel="prefetch" href="/assets/js/676.ff44b5dc.js"><link rel="prefetch" href="/assets/js/677.41a8087a.js"><link rel="prefetch" href="/assets/js/678.f0eb8d04.js"><link rel="prefetch" href="/assets/js/679.db78199e.js"><link rel="prefetch" href="/assets/js/68.08607c89.js"><link rel="prefetch" href="/assets/js/680.8fded9d4.js"><link rel="prefetch" href="/assets/js/681.0b019dfd.js"><link rel="prefetch" href="/assets/js/682.746e9190.js"><link rel="prefetch" href="/assets/js/683.d5c00845.js"><link rel="prefetch" href="/assets/js/684.b3207cad.js"><link rel="prefetch" href="/assets/js/685.d78f18ba.js"><link rel="prefetch" href="/assets/js/686.5aaecd19.js"><link rel="prefetch" href="/assets/js/687.821a06f4.js"><link rel="prefetch" href="/assets/js/688.8bbc1890.js"><link rel="prefetch" href="/assets/js/689.79b49e8c.js"><link rel="prefetch" href="/assets/js/69.509245d6.js"><link rel="prefetch" href="/assets/js/690.fa62f9dd.js"><link rel="prefetch" href="/assets/js/691.d3eb1a60.js"><link rel="prefetch" href="/assets/js/692.738f14bb.js"><link rel="prefetch" href="/assets/js/693.e6a497a2.js"><link rel="prefetch" href="/assets/js/694.6eea1c54.js"><link rel="prefetch" href="/assets/js/695.88e6acee.js"><link rel="prefetch" href="/assets/js/696.de10297f.js"><link rel="prefetch" href="/assets/js/697.96d04062.js"><link rel="prefetch" href="/assets/js/699.f11fc627.js"><link rel="prefetch" href="/assets/js/7.c16198b8.js"><link rel="prefetch" href="/assets/js/70.5f6285b1.js"><link rel="prefetch" href="/assets/js/700.93d48f59.js"><link rel="prefetch" href="/assets/js/701.b861f29a.js"><link rel="prefetch" href="/assets/js/702.dc82e05c.js"><link rel="prefetch" href="/assets/js/703.625ce87c.js"><link rel="prefetch" href="/assets/js/704.005a0a7c.js"><link rel="prefetch" href="/assets/js/705.16ad9230.js"><link rel="prefetch" href="/assets/js/706.4eead30a.js"><link rel="prefetch" href="/assets/js/707.730306ce.js"><link rel="prefetch" href="/assets/js/708.e37e743a.js"><link rel="prefetch" href="/assets/js/709.f2144f52.js"><link rel="prefetch" href="/assets/js/71.d5d0dae5.js"><link rel="prefetch" href="/assets/js/710.ee9d9b17.js"><link rel="prefetch" href="/assets/js/711.2813c338.js"><link rel="prefetch" href="/assets/js/712.e801bce4.js"><link rel="prefetch" href="/assets/js/713.21fc267c.js"><link rel="prefetch" href="/assets/js/714.4ec35525.js"><link rel="prefetch" href="/assets/js/715.fdc3cc84.js"><link rel="prefetch" href="/assets/js/716.324932ad.js"><link rel="prefetch" href="/assets/js/717.a072a66f.js"><link rel="prefetch" href="/assets/js/718.575e0305.js"><link rel="prefetch" href="/assets/js/719.5fdd55de.js"><link rel="prefetch" href="/assets/js/72.25648231.js"><link rel="prefetch" href="/assets/js/720.61477f23.js"><link rel="prefetch" href="/assets/js/721.c8bdab00.js"><link rel="prefetch" href="/assets/js/722.9255f385.js"><link rel="prefetch" href="/assets/js/723.f27792a4.js"><link rel="prefetch" href="/assets/js/724.cd504f88.js"><link rel="prefetch" href="/assets/js/725.55c845fa.js"><link rel="prefetch" href="/assets/js/726.bb49a9db.js"><link rel="prefetch" href="/assets/js/727.53d587fe.js"><link rel="prefetch" href="/assets/js/728.86972387.js"><link rel="prefetch" href="/assets/js/729.02fa0263.js"><link rel="prefetch" href="/assets/js/73.29902c1f.js"><link rel="prefetch" href="/assets/js/730.817156d1.js"><link rel="prefetch" href="/assets/js/731.6f5d6735.js"><link rel="prefetch" href="/assets/js/732.9a5ff781.js"><link rel="prefetch" href="/assets/js/733.bcb13916.js"><link rel="prefetch" href="/assets/js/734.11482b19.js"><link rel="prefetch" href="/assets/js/735.8c0d62f3.js"><link rel="prefetch" href="/assets/js/736.06465705.js"><link rel="prefetch" href="/assets/js/737.79741d87.js"><link rel="prefetch" href="/assets/js/738.cad12ff9.js"><link rel="prefetch" href="/assets/js/739.cb09e552.js"><link rel="prefetch" href="/assets/js/74.bcf666a0.js"><link rel="prefetch" href="/assets/js/740.029b1950.js"><link rel="prefetch" href="/assets/js/741.b937216a.js"><link rel="prefetch" href="/assets/js/742.ec02c706.js"><link rel="prefetch" href="/assets/js/743.70a96283.js"><link rel="prefetch" href="/assets/js/744.909b870c.js"><link rel="prefetch" href="/assets/js/745.80defb2d.js"><link rel="prefetch" href="/assets/js/746.fb972248.js"><link rel="prefetch" href="/assets/js/747.1a7b52fd.js"><link rel="prefetch" href="/assets/js/748.036f5d16.js"><link rel="prefetch" href="/assets/js/749.bd9a413d.js"><link rel="prefetch" href="/assets/js/75.23c5a54d.js"><link rel="prefetch" href="/assets/js/750.3f1ae8f5.js"><link rel="prefetch" href="/assets/js/751.8897bc9f.js"><link rel="prefetch" href="/assets/js/752.9b387659.js"><link rel="prefetch" href="/assets/js/753.f411ce21.js"><link rel="prefetch" href="/assets/js/754.26def684.js"><link rel="prefetch" href="/assets/js/755.923aff62.js"><link rel="prefetch" href="/assets/js/756.9965743a.js"><link rel="prefetch" href="/assets/js/757.0c6bbbfd.js"><link rel="prefetch" href="/assets/js/758.a830f8b1.js"><link rel="prefetch" href="/assets/js/759.987cad77.js"><link rel="prefetch" href="/assets/js/76.f54f3d4f.js"><link rel="prefetch" href="/assets/js/760.9f2652a0.js"><link rel="prefetch" href="/assets/js/761.df01a0ee.js"><link rel="prefetch" href="/assets/js/762.e0c05a1a.js"><link rel="prefetch" href="/assets/js/763.da8a60bd.js"><link rel="prefetch" href="/assets/js/764.9f2a2830.js"><link rel="prefetch" href="/assets/js/765.44e61161.js"><link rel="prefetch" href="/assets/js/766.cd7da8c1.js"><link rel="prefetch" href="/assets/js/767.6ea1fea2.js"><link rel="prefetch" href="/assets/js/768.91529b8f.js"><link rel="prefetch" href="/assets/js/769.194d7a3e.js"><link rel="prefetch" href="/assets/js/77.3d43a163.js"><link rel="prefetch" href="/assets/js/770.227fd5b9.js"><link rel="prefetch" href="/assets/js/771.44d5e37e.js"><link rel="prefetch" href="/assets/js/772.234d9bf6.js"><link rel="prefetch" href="/assets/js/773.ff1dfb6a.js"><link rel="prefetch" href="/assets/js/774.d401364f.js"><link rel="prefetch" href="/assets/js/775.37a7cf41.js"><link rel="prefetch" href="/assets/js/776.0cd10853.js"><link rel="prefetch" href="/assets/js/777.599a3a48.js"><link rel="prefetch" href="/assets/js/778.eef27a95.js"><link rel="prefetch" href="/assets/js/779.29351199.js"><link rel="prefetch" href="/assets/js/78.fd0780ac.js"><link rel="prefetch" href="/assets/js/780.74caed94.js"><link rel="prefetch" href="/assets/js/781.ee0fa9b5.js"><link rel="prefetch" href="/assets/js/782.7cffed09.js"><link rel="prefetch" href="/assets/js/783.7f01f518.js"><link rel="prefetch" href="/assets/js/784.5f65e3d7.js"><link rel="prefetch" href="/assets/js/785.d7e13880.js"><link rel="prefetch" href="/assets/js/786.6110d12f.js"><link rel="prefetch" href="/assets/js/787.334a5cdd.js"><link rel="prefetch" href="/assets/js/788.f261bc71.js"><link rel="prefetch" href="/assets/js/789.b6d74f7d.js"><link rel="prefetch" href="/assets/js/79.7b5d6224.js"><link rel="prefetch" href="/assets/js/790.fa948ec4.js"><link rel="prefetch" href="/assets/js/791.22080013.js"><link rel="prefetch" href="/assets/js/792.31ce806c.js"><link rel="prefetch" href="/assets/js/793.9fd0c56f.js"><link rel="prefetch" href="/assets/js/794.44a8cd9c.js"><link rel="prefetch" href="/assets/js/795.9f8346e5.js"><link rel="prefetch" href="/assets/js/796.0de9c7a1.js"><link rel="prefetch" href="/assets/js/797.83ac32a6.js"><link rel="prefetch" href="/assets/js/798.393fc81d.js"><link rel="prefetch" href="/assets/js/799.c1fb3981.js"><link rel="prefetch" href="/assets/js/8.3275ed06.js"><link rel="prefetch" href="/assets/js/80.df3f0a1f.js"><link rel="prefetch" href="/assets/js/800.2832adeb.js"><link rel="prefetch" href="/assets/js/801.04c58fc4.js"><link rel="prefetch" href="/assets/js/81.3d90ef6b.js"><link rel="prefetch" href="/assets/js/82.2d42448d.js"><link rel="prefetch" href="/assets/js/83.900b4de2.js"><link rel="prefetch" href="/assets/js/84.ff570f67.js"><link rel="prefetch" href="/assets/js/85.e3b3af39.js"><link rel="prefetch" href="/assets/js/86.17b5aedc.js"><link rel="prefetch" href="/assets/js/87.f931d1d6.js"><link rel="prefetch" href="/assets/js/88.d55863cd.js"><link rel="prefetch" href="/assets/js/89.15a9a6d7.js"><link rel="prefetch" href="/assets/js/9.04948a9d.js"><link rel="prefetch" href="/assets/js/90.22696aa9.js"><link rel="prefetch" href="/assets/js/91.f1bd8a2e.js"><link rel="prefetch" href="/assets/js/92.85733094.js"><link rel="prefetch" href="/assets/js/93.59bacfd7.js"><link rel="prefetch" href="/assets/js/94.a5f9b7a0.js"><link rel="prefetch" href="/assets/js/95.be52d65a.js"><link rel="prefetch" href="/assets/js/96.0b76ba8e.js"><link rel="prefetch" href="/assets/js/97.28183cd4.js"><link rel="prefetch" href="/assets/js/98.2d22829c.js"><link rel="prefetch" href="/assets/js/99.ed602a20.js">
    <link rel="stylesheet" href="/assets/css/0.styles.a3df589e.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">AJ</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link">主页</a></div><div class="nav-item"><a href="/op/" class="nav-link">Devops</a></div><div class="nav-item"><a href="/golang/" class="nav-link">Go</a></div><div class="nav-item"><a href="/go-block/" class="nav-link">区块链</a></div><div class="nav-item"><a href="/k8s/" class="nav-link">k8s</a></div><div class="nav-item"><a href="/about.html" class="nav-link">关于我</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="更多" class="dropdown-title"><span class="title">更多</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/go-learning/" class="nav-link">go-learning</a></li><li class="dropdown-item"><!----> <a href="/post/flutter-guide/" aria-current="page" class="nav-link router-link-exact-active router-link-active">flutter</a></li><li class="dropdown-item"><!----> <a href="/mysql/" class="nav-link">mysql</a></li><li class="dropdown-item"><!----> <a href="/python/" class="nav-link">python</a></li></ul></div></div> <a href="https://github.com/ChinaArJun" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link">主页</a></div><div class="nav-item"><a href="/op/" class="nav-link">Devops</a></div><div class="nav-item"><a href="/golang/" class="nav-link">Go</a></div><div class="nav-item"><a href="/go-block/" class="nav-link">区块链</a></div><div class="nav-item"><a href="/k8s/" class="nav-link">k8s</a></div><div class="nav-item"><a href="/about.html" class="nav-link">关于我</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="更多" class="dropdown-title"><span class="title">更多</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/go-learning/" class="nav-link">go-learning</a></li><li class="dropdown-item"><!----> <a href="/post/flutter-guide/" aria-current="page" class="nav-link router-link-exact-active router-link-active">flutter</a></li><li class="dropdown-item"><!----> <a href="/mysql/" class="nav-link">mysql</a></li><li class="dropdown-item"><!----> <a href="/python/" class="nav-link">python</a></li></ul></div></div> <a href="https://github.com/ChinaArJun" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav> <div></div> <div style="padding-left:1.5rem;"><div></div></div> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>flutter 入门指南</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/post/flutter-guide/#前言" class="sidebar-link">前言</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#开发系统" class="sidebar-link">开发系统</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#shell" class="sidebar-link">shell</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#翻译" class="sidebar-link">翻译</a></li></ul></li><li><a href="/post/flutter-guide/#安装" class="sidebar-link">安装</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#网络问题" class="sidebar-link">网络问题</a></li></ul></li><li><a href="/post/flutter-guide/#编辑器" class="sidebar-link">编辑器</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#vs-code" class="sidebar-link">VS Code</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#vim" class="sidebar-link">vim</a></li></ul></li><li><a href="/post/flutter-guide/#运行第一个应用" class="sidebar-link">运行第一个应用</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#热加载" class="sidebar-link">热加载</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#真机运行" class="sidebar-link">真机运行</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#问题" class="sidebar-link">问题</a></li></ul></li><li><a href="/post/flutter-guide/#动手写第一个应用" class="sidebar-link">动手写第一个应用</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/post/flutter-guide/#dart" class="sidebar-link">Dart</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#环境" class="sidebar-link">环境</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#main-函数" class="sidebar-link">main() 函数</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#变量" class="sidebar-link">变量</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#内置类型-built-in-types" class="sidebar-link">内置类型 (Built-in Types)</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#函数" class="sidebar-link">函数</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#操作符" class="sidebar-link">操作符</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#类" class="sidebar-link">类</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#异步" class="sidebar-link">异步</a></li></ul></li><li><a href="/post/flutter-guide/#布局" class="sidebar-link">布局</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#constraint-box" class="sidebar-link">Constraint Box</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#text-widget" class="sidebar-link">Text Widget</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#container-widget" class="sidebar-link">Container Widget</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#row-column-widget" class="sidebar-link">Row &amp; Column Widget</a></li></ul></li><li><a href="/post/flutter-guide/#material-design" class="sidebar-link">Material Design</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#appbar" class="sidebar-link">AppBar</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#icon" class="sidebar-link">Icon</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#tabbar" class="sidebar-link">TabBar</a></li></ul></li><li><a href="/post/flutter-guide/#布局实践" class="sidebar-link">布局实践</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#垂直居中一个-300-300-固定宽高的组件" class="sidebar-link">垂直居中一个 300 * 300 固定宽高的组件</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#垂直居中多行文字" class="sidebar-link">垂直居中多行文字</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#左侧固定-50px，中间自适应，右侧固定-50px" class="sidebar-link">左侧固定 50px，中间自适应，右侧固定 50px</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#平分5栏" class="sidebar-link">平分5栏</a></li></ul></li><li><a href="/post/flutter-guide/#手势" class="sidebar-link">手势</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/post/flutter-guide/#状态" class="sidebar-link">状态</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#生命周期" class="sidebar-link">生命周期</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#counter" class="sidebar-link">Counter</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#状态管理方案" class="sidebar-link">状态管理方案</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#valuenotifier" class="sidebar-link">ValueNotifier</a></li></ul></li><li><a href="/post/flutter-guide/#调试" class="sidebar-link">调试</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#如何像-devtool-inspector-一样定位元素" class="sidebar-link">如何像 Devtool Inspector 一样定位元素</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#如何打印数据至控制台" class="sidebar-link">如何打印数据至控制台</a></li></ul></li><li><a href="/post/flutter-guide/#路由" class="sidebar-link">路由</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#navigator" class="sidebar-link">Navigator</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#路由传值" class="sidebar-link">路由传值</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#命名路由-named-routes" class="sidebar-link">命名路由 (Named Routes)</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#路由管理" class="sidebar-link">路由管理</a></li></ul></li><li><a href="/post/flutter-guide/#包管理" class="sidebar-link">包管理</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#引入库-importing-a-library" class="sidebar-link">引入库 (Importing a Library)</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#如何引入另一个文件" class="sidebar-link">如何引入另一个文件</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#依赖" class="sidebar-link">依赖</a></li></ul></li><li><a href="/post/flutter-guide/#permission-api" class="sidebar-link">Permission API</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/post/flutter-guide/#http-请求" class="sidebar-link">http 请求</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#dio" class="sidebar-link">Dio</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#json" class="sidebar-link">JSON</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#streambuilder-futurebuilder" class="sidebar-link">StreamBuilder &amp;&amp; FutureBuilder</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#memoization" class="sidebar-link">Memoization</a></li></ul></li><li><a href="/post/flutter-guide/#存储" class="sidebar-link">存储</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/post/flutter-guide/#key-value-存储" class="sidebar-link">key/value 存储</a></li><li class="sidebar-sub-header"><a href="/post/flutter-guide/#database" class="sidebar-link">database</a></li></ul></li><li><a href="/post/flutter-guide/#参考" class="sidebar-link">参考</a><ul class="sidebar-sub-headers"></ul></li></ul></section></li></ul> </aside> <!----> <!----> <main class="page"><div class="theme-default-content" style="margin-bottom:-5rem;"><div class="bar"><div class="bar-intro"><div class="text">
      流逝的是岁月，不变的是情怀.
        </div> <div class="text">
      坚持学习，是为了成就更好的自己. <br></div> <div>公众号[中关村程序员]</div></div></div> <!----></div> <div class="theme-default-content content__default"><h1 id="flutter"><a href="#flutter" class="header-anchor">#</a> flutter</h1> <p>flutter 的出现不得不说是激动人心的，你可以以 React-Style 的方式写多端应用。而相比 RN 而言，它自身的版本迭代也比较积极。</p> <h2 id="前言"><a href="#前言" class="header-anchor">#</a> 前言</h2> <h3 id="开发系统"><a href="#开发系统" class="header-anchor">#</a> 开发系统</h3> <p>我在 MacOS 上进行开发</p> <h3 id="shell"><a href="#shell" class="header-anchor">#</a> shell</h3> <p>我的 shell 是 <code>zsh</code>，配置文件在 <code>~/.zshrc</code>。如果你们的是</p> <ul><li>mobile -&gt; android</li> <li>基础 -&gt; 前端 css 与 react</li></ul> <p>建议跟着目录走</p> <h3 id="翻译"><a href="#翻译" class="header-anchor">#</a> 翻译</h3> <ul><li>compile-time (编译时)</li> <li>run-time (运行时)</li> <li>generic type (泛型)</li></ul> <h2 id="安装"><a href="#安装" class="header-anchor">#</a> 安装</h2> <div class="language-shell extra-class"><pre class="language-shell"><code><span class="token comment"># 安装到自己感兴趣的位置，这里安装在 /app 目录下</span>
<span class="token builtin class-name">cd</span> /app
<span class="token function">curl</span> -O https://storage.googleapis.com/flutter_infra/releases/stable/macos/flutter_macos_v1.2.1-stable.zip
<span class="token function">unzip</span> flutter_macos_v1.2.1-stable.zip

<span class="token comment"># 写入到环境变量</span>
<span class="token builtin class-name">echo</span> <span class="token string">'export PATH=&quot;<span class="token environment constant">$PATH</span>:/app/flutter/bin&quot;'</span> <span class="token operator">&gt;&gt;</span> ~/.zshrc

<span class="token comment"># 选择你工作所使用的 shell，可以是 bash 也可以是 zsh</span>
<span class="token comment"># echo 'export PATH=&quot;$PATH:/app/flutter/bin&quot;' &gt;&gt; ~/.bashrc</span>

<span class="token comment"># 执行生效</span>
<span class="token builtin class-name">source</span> ~/.zshrc
</code></pre></div><p>完成以上命令后，运行命令 <code>flutter doctor</code> 查看是否安装成功，如果没有则有对相关扩展的安装提示。有以下扩展，可以参考相关文章进行安装</p> <ul><li>Android toolchain (SDK)</li> <li>IOS toolchain</li> <li>Android Studio</li></ul> <h3 id="网络问题"><a href="#网络问题" class="header-anchor">#</a> 网络问题</h3> <p>在国内，如果出现了关于网络的问题，官方早已想到了解决方案，参考本篇文章 <a href="https://flutter.dev/community/china" target="_blank" rel="noopener noreferrer">Using Flutter in China<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>。</p> <p>执行以下命令更换安装包的源，你也可以选择其它的源</p> <div class="language-shell extra-class"><pre class="language-shell"><code><span class="token comment"># 写入你自己的 shell 文件</span>
<span class="token function">cat</span> <span class="token operator">&lt;&lt;</span>EOF <span class="token operator">&gt;&gt;</span> ~/.zshrc
<span class="token builtin class-name">export</span> <span class="token assign-left variable">PUB_HOSTED_URL</span><span class="token operator">=</span>https://pub.flutter-io.cn
<span class="token builtin class-name">export</span> <span class="token assign-left variable">FLUTTER_STORAGE_BASE_URL</span><span class="token operator">=</span>https://storage.flutter-io.cn
EOF
</code></pre></div><h2 id="编辑器"><a href="#编辑器" class="header-anchor">#</a> 编辑器</h2> <h3 id="vs-code"><a href="#vs-code" class="header-anchor">#</a> VS Code</h3> <p>需要与插件 Dart 配合使用</p> <p><strong>在 VS Code 下，对启动，调试，热加载，Goto Path 以及自动补全都相当方便，强烈推荐。</strong></p> <blockquote><p>参考官方文档 https://flutter.dev/docs/development/tools/vs-code</p></blockquote> <h3 id="vim"><a href="#vim" class="header-anchor">#</a> vim</h3> <ul><li><a href="https://github.com/dart-lang/dart-vim-plugin" target="_blank" rel="noopener noreferrer">dart-vim-plugin<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <p>使用该插件无法正确缩进圆括号内代码</p> <blockquote><p>参考 https://github.com/dart-lang/dart-vim-plugin#faq</p></blockquote> <h2 id="运行第一个应用"><a href="#运行第一个应用" class="header-anchor">#</a> 运行第一个应用</h2> <p>使用以下命令新建一个项目并使用 VS Code 打开。当然你也可以选择使用编辑器新建项目</p> <div class="language-shell extra-class"><pre class="language-shell"><code><span class="token builtin class-name">cd</span> ~/flutter-examples

<span class="token comment"># 新建项目时会自动执行 flutter packages get 来装包</span>
flutter create hello-world 

<span class="token comment"># 进入项目目录</span>
<span class="token builtin class-name">cd</span> hello-world

<span class="token comment"># 装包，新建项目时已自动执行</span>
<span class="token comment"># flutter packages get</span>

<span class="token comment"># 列出模拟器列表</span>
flutter emulators

<span class="token comment"># 启动一个模拟器，输入 emulatorId 的前缀即可</span>
flutter emulators --lauch <span class="token operator">&lt;</span>emulatorId<span class="token operator">&gt;</span>

<span class="token comment"># 查看设备列表</span>
flutter devices

<span class="token comment"># 运行，成功后可以在模拟器中看见界面</span>
flutter run

<span class="token comment"># 如果有多个设置，选择某个设备进行调试，输入前缀即可</span>
flutter run -d <span class="token operator">&lt;</span>deviceId<span class="token operator">&gt;</span>
</code></pre></div><p><img src="https://flutter.dev/assets/get-started/ios/starter-app-5e284e57b8dce587ea1dfdac7da616e6ec9dc263a409a9a8f99cf836340f47b8.png" alt="运行成功界面"></p> <p>如果没有走完流程，也非常正常，通向成功的道路从不一帆风顺，学习新技术总会遇到不少坑。这里列举新建项目时出现的几个小问题</p> <h3 id="热加载"><a href="#热加载" class="header-anchor">#</a> 热加载</h3> <p>你会发现你保存文件时没有更新界面，这是因为你使用了命令启动，并未与编辑器进行绑定。</p> <p>使用命令 <code>flutter run</code> 运行成功后，按键 <code>r</code> 进行热加载，<code>R</code> 进行热重启，会刷新应用状态。</p> <h3 id="真机运行"><a href="#真机运行" class="header-anchor">#</a> 真机运行</h3> <p>在 Android 上真机运行，需要打开</p> <ul><li>开发者选项</li> <li>USB 调试</li> <li>USB 安装</li></ul> <h3 id="问题"><a href="#问题" class="header-anchor">#</a> 问题</h3> <h4 id="装包卡顿"><a href="#装包卡顿" class="header-anchor">#</a> 装包卡顿</h4> <p>装包卡顿有可能是因为国内网络的原因，请参考以上章节 <a href="">网络问题</a></p> <p>如果还有问题，在 flutter 创建的项目根目录中定位文件 <code>./android/build.gradle</code>，进行如下修改</p> <div class="language-gradle extra-class"><pre class="language-text"><code>// 修改前文件
buildscript {
    repositories {
        google()
        jcenter()
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}


// 修改后文件
buildscript {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven { url 'https://maven.aliyun.com/repository/jcenter' }
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
    }
}
allprojects {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven { url 'https://maven.aliyun.com/repository/jcenter' }
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
    }
}
</code></pre></div><h4 id="命令锁住"><a href="#命令锁住" class="header-anchor">#</a> 命令锁住</h4> <p>在执行 flutter 命令时，有可能遇到命令被锁住的情况</p> <div class="language- extra-class"><pre class="language-text"><code>Waiting for another flutter command to release the startup lock...
</code></pre></div><blockquote><p>更多解决方案参考 https://github.com/flutter/flutter/issues/17422</p></blockquote> <p>使用以下命令解决</p> <div class="language-shell extra-class"><pre class="language-shell"><code><span class="token comment"># 删除 bin 目录下的 lockfile</span>
<span class="token function">rm</span> /app/flutter/bin/cache/lockfile
</code></pre></div><h2 id="动手写第一个应用"><a href="#动手写第一个应用" class="header-anchor">#</a> 动手写第一个应用</h2> <p>动手写一个 flutter 的 <code>hello, world</code> 应用。编辑 /lib/main.dart 如下</p> <div class="language-Dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'package:flutter/material.dart'</span><span class="token punctuation">;</span>

<span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token function">runApp</span><span class="token punctuation">(</span><span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">StatelessWidget</span> <span class="token punctuation">{</span>
  <span class="token metadata symbol">@override</span>
  Widget <span class="token function">build</span><span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'hello, world'</span><span class="token punctuation">,</span> textDirection<span class="token punctuation">:</span> TextDirection<span class="token punctuation">.</span>ltr<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>在模拟器或真机上运行。运行后是一个黑色界面，左上角写着 <code>hello, world</code> 虽然丑了点，好歹麻雀虽小五脏俱全。另外，如果你写过 React, 发现它和 React 的写法如此相像。人在学习新东西时，如果与旧知识有关联性，能够学的很快。</p> <p>你会发现，<code>StateLessWidget</code> 与 React 的 <code>Component</code> 相似，而 <code>build</code> 函数与 React 的 <code>build</code> 相似。</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token keyword">import</span> React<span class="token punctuation">,</span> <span class="token punctuation">{</span> Component <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> render <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-dom'</span><span class="token punctuation">;</span>

<span class="token function">render</span><span class="token punctuation">(</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">App</span></span> <span class="token punctuation">/&gt;</span></span><span class="token punctuation">,</span> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'app'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span><span class="token plain-text">hello, world</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="dart"><a href="#dart" class="header-anchor">#</a> Dart</h2> <p>敲完了第一个应用，你会发现 <code>Text('hello, world', textDirection: TextDirection.ltr)</code> 这个函数很怪，有点像 js 的 <code>Text('hello, world', { textDirection: TextDirection.ltr })</code> 或者 python 的 <code>Text('hello, world', textDirection=TextDirection.ltr )</code>。</p> <p>这时候，你发现 <code>flutter</code> 仅仅是依赖于 <code>Dart</code> 下的移动开发框架，现在有必要学习一下 <code>Dart</code> 的语法了。</p> <p><code>Dart</code>  是一门强类型的静态语言，而且必须加分号。</p> <blockquote><p>如果你需要更为详细的文档，参考官方文档 https://www.dartlang.org/guides/language/language-tour</p></blockquote> <h3 id="环境"><a href="#环境" class="header-anchor">#</a> 环境</h3> <p>正如 codepen 可以在线学习与测试前端。你也可以在 <a href="https://dartpad.dartlang.org" target="_blank" rel="noopener noreferrer">DartPad<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> 中，打开浏览器在线学习 Dart 语言。</p> <h3 id="main-函数"><a href="#main-函数" class="header-anchor">#</a> main() 函数</h3> <p>入口函数，如同 C 语言一样。</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'hello, world'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="变量"><a href="#变量" class="header-anchor">#</a> 变量</h3> <p><code>Dart</code> 是强类型语言，但也可以直接使用 <code>var</code> 声明一个变量。</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
  int b <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span>

  <span class="token keyword">const</span> c <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
  <span class="token keyword">final</span> d <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span>

  <span class="token keyword">dynamic</span> e <span class="token operator">=</span> <span class="token string">'hello, world'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h4 id="final-和-const-的区别是什么"><a href="#final-和-const-的区别是什么" class="header-anchor">#</a> <code>final</code> 和 <code>const</code> 的区别是什么</h4> <p><code>const</code> 编译时确定，<code>const</code> 运行时确定。</p> <p><strong>了解两者不同后，以下示例的输出是什么</strong></p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">void</span> <span class="token function">test1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">final</span> foo <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  foo<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
 
  <span class="token function">print</span><span class="token punctuation">(</span>foo<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token function">test2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> foo <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  foo<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
 
  <span class="token function">print</span><span class="token punctuation">(</span>foo<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">test1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">test2</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">final</span> l <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> x<span class="token operator">+</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> l <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> x<span class="token operator">+</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h4 id="dynamic-与-var-的区别是什么"><a href="#dynamic-与-var-的区别是什么" class="header-anchor">#</a> <code>dynamic</code> 与 <code>var</code> 的区别是什么</h4> <p>你运行完以下代码，便可以知道两者的区别。</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> foo <span class="token operator">=</span> <span class="token string">'hello'</span><span class="token punctuation">;</span>
  <span class="token keyword">var</span> <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>

  <span class="token keyword">dynamic</span> bar <span class="token operator">=</span> <span class="token string">'hello'</span><span class="token punctuation">;</span>
  bar <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="内置类型-built-in-types"><a href="#内置类型-built-in-types" class="header-anchor">#</a> 内置类型 (Built-in Types)</h3> <blockquote><p>参考类型风格指南建议 https://www.dartlang.org/guides/language/effective-dart/design#types</p></blockquote> <p>Dart 有如下数据类型，这里先简单介绍一下常用类型</p> <ul><li>number
<ul><li>int</li> <li>number</li></ul></li> <li>string</li> <li>boolean</li> <li>list (array)</li> <li>set</li> <li>map</li> <li>rune</li> <li>symbol</li></ul> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// int</span>
  <span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token function">print</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// double</span>
  <span class="token keyword">var</span> b <span class="token operator">=</span> <span class="token number">3.14</span><span class="token punctuation">;</span>
  <span class="token function">print</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// string</span>
  <span class="token comment">// ${exp} 字符串变量解析。恩，有点像 shell</span>
  <span class="token keyword">var</span> s <span class="token operator">=</span> <span class="token string">'$a + $b = ${a + b}'</span><span class="token punctuation">;</span>
  <span class="token function">print</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span>
</code></pre></div><h4 id="list"><a href="#list" class="header-anchor">#</a> List</h4> <blockquote><p>TODO
在 <code>Dart</code> 中，<code>List</code>，<code>Set</code> 和 <code>Collection</code> 统称为 Collection。它们有公共的方法 <code>forEach</code> 与 <code>map</code> 等。</p></blockquote> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> l <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

  <span class="token comment">// [1, 2, 3]</span>
  <span class="token function">print</span><span class="token punctuation">(</span>l<span class="token punctuation">)</span><span class="token punctuation">;</span>

  l<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  l<span class="token punctuation">.</span><span class="token function">addAll</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// [1, 2, 3, 4, 5, 6]</span>
  <span class="token function">print</span><span class="token punctuation">(</span>l<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// 1</span>
  <span class="token function">print</span><span class="token punctuation">(</span>l<span class="token punctuation">.</span>first<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// [2, 3, 4, 5, 6]</span>
  <span class="token function">print</span><span class="token punctuation">(</span>l<span class="token punctuation">.</span><span class="token function">skip</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">var</span> ll <span class="token operator">=</span> l<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> x <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">var</span> lll <span class="token operator">=</span> l<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> x <span class="token operator">+</span> <span class="token number">3</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">print</span><span class="token punctuation">(</span>ll<span class="token punctuation">.</span>runtimeType<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>另外，在 js 中数组有一个我最喜欢的 API <code>Array.prototype.reduce</code>。在 <code>dart</code> 中可以使用 <code>fold</code> 替代</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token comment">// 21</span>
<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span>acc<span class="token punctuation">,</span> x<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> acc <span class="token operator">+</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 121</span>
<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">fold</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>acc<span class="token punctuation">,</span> x<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> acc <span class="token operator">+</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><blockquote><p>Q: 什么是泛型 (generic type)</p></blockquote> <h4 id="set"><a href="#set" class="header-anchor">#</a> Set</h4> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 或者 Set&lt;String&gt; colors = {};</span>
  <span class="token keyword">var</span> colors <span class="token operator">=</span> <span class="token function">Set</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  colors<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">'red'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  colors<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token string">'blue'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">print</span><span class="token punctuation">(</span>colors<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">print</span><span class="token punctuation">(</span>colors<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> x<span class="token punctuation">)</span><span class="token punctuation">)</span>

  <span class="token keyword">assert</span><span class="token punctuation">(</span>colors<span class="token punctuation">.</span><span class="token function">contains</span><span class="token punctuation">(</span><span class="token string">'red'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h4 id="map"><a href="#map" class="header-anchor">#</a> Map</h4> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// Map&lt;String, int&gt; = {};</span>
  <span class="token keyword">var</span> o <span class="token operator">=</span> <span class="token function">Map</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  o<span class="token punctuation">[</span><span class="token string">'a'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
  o<span class="token punctuation">[</span><span class="token string">'b'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span>
  <span class="token function">print</span><span class="token punctuation">(</span>o<span class="token punctuation">)</span><span class="token punctuation">;</span>

  o <span class="token operator">=</span> <span class="token punctuation">{</span>
    <span class="token string">'a'</span><span class="token punctuation">:</span> <span class="token number">3</span><span class="token punctuation">,</span>
    <span class="token string">'b'</span><span class="token punctuation">:</span> <span class="token number">4</span><span class="token punctuation">,</span>
    <span class="token string">'c'</span><span class="token punctuation">:</span> <span class="token number">5</span>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token function">print</span><span class="token punctuation">(</span>o<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">assert</span><span class="token punctuation">(</span>o<span class="token punctuation">.</span><span class="token function">containsKey</span><span class="token punctuation">(</span><span class="token string">'a'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  o<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span>k<span class="token punctuation">,</span> v<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'$k: $v'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>

  <span class="token function">print</span><span class="token punctuation">(</span>o<span class="token punctuation">.</span>entries<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">print</span><span class="token punctuation">(</span>o<span class="token punctuation">.</span>entries<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>o<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token string">'${o.key}: ${o.value}'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="函数"><a href="#函数" class="header-anchor">#</a> 函数</h3> <div class="language-dart extra-class"><pre class="language-dart"><code>bool <span class="token function">isZero</span><span class="token punctuation">(</span>int n<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> n <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 在 [] 中代表可选参数</span>
bool <span class="token function">isZero</span><span class="token punctuation">(</span><span class="token punctuation">[</span>int n<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> n <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 默认参数</span>
bool <span class="token function">isZero</span><span class="token punctuation">(</span><span class="token punctuation">[</span>int n <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> n <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">;</span> 
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// 箭头函数</span>
<span class="token comment">// 如 javascript 一样，相比 js 而言它只是少了一个 = 等于号</span>
<span class="token comment">// javascript 👉 const isZero = (n) =&gt; n === 0;</span>
bool <span class="token function">isZero</span><span class="token punctuation">(</span>int n<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> n <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">;</span>


<span class="token comment">// 匿名函数</span>
<span class="token comment">// 如 javascript 一样，相比 js 而言参数必须带括号</span>
<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> x<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> x <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="操作符"><a href="#操作符" class="header-anchor">#</a> 操作符</h3> <h4 id=""><a href="#" class="header-anchor">#</a></h4> <h3 id="类"><a href="#类" class="header-anchor">#</a> 类</h3> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">class</span> <span class="token class-name">Point</span> <span class="token punctuation">{</span>
  <span class="token keyword">final</span> num x<span class="token punctuation">;</span>
  <span class="token keyword">final</span> num y<span class="token punctuation">;</span>
  <span class="token keyword">final</span> num z<span class="token punctuation">;</span>

  <span class="token function">Point</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">:</span> x <span class="token operator">=</span> x<span class="token punctuation">,</span> y <span class="token operator">=</span> y<span class="token punctuation">,</span> z <span class="token operator">=</span> x <span class="token operator">+</span> y<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> p <span class="token operator">=</span> <span class="token function">Point</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">print</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>z<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="异步"><a href="#异步" class="header-anchor">#</a> 异步</h3> <p>在 js 中有承诺(Promise)，在 Dart 中也有未来(Future)</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token comment">// 与 js 的不同就是，dart 把 async 写到最后边了...</span>
Future <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">async</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> res <span class="token operator">=</span> <span class="token keyword">await</span> request<span class="token punctuation">.</span><span class="token keyword">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="布局"><a href="#布局" class="header-anchor">#</a> 布局</h2> <p>熟悉了 <code>dart</code> 的语法之后，可以动手画一个漂亮的界面 (UI)了。布局组件是构成 UI 的重要一步</p> <blockquote><p>更多布局组件参考官方文档 https://flutter.dev/docs/development/ui/widgets/layout</p></blockquote> <ul><li>Padding</li> <li>Container</li> <li>Row</li> <li>Column</li> <li>Center</li> <li>RenderBox</li> <li>SizedBox</li> <li>ConstrainedBox</li> <li>Center</li> <li>ListView</li> <li>Text</li> <li>Image</li> <li>Transform</li> <li>Opacity</li></ul> <h3 id="constraint-box"><a href="#constraint-box" class="header-anchor">#</a> Constraint Box</h3> <p>正如 html 中元素有 block，inline，inline-box 之分。flutter 也有类似三类约束</p> <ul><li>尽可能撑高成宽   👉 <code>Container</code> 和 <code>Center</code></li> <li>与子组件等高等宽 👉 <code>Transform</code> 和 <code>Opacity</code></li> <li>特定尺寸         👉 <code>Text</code> 和 <code>Image</code></li></ul> <p>当然上边只是一部分组件的约束，<code>Container</code> 也可以指定宽高，变为第三类。另外还有不受此约束的 <code>ListView</code> 与 <code>Row/Column</code>。</p> <p>接下来介绍几种重要且常见的组件，如 <code>Container</code>，<code>Row</code>，<code>Column</code></p> <h3 id="text-widget"><a href="#text-widget" class="header-anchor">#</a> Text Widget</h3> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token function">Text</span><span class="token punctuation">(</span>
  textDirection<span class="token punctuation">:</span> TextDirection<span class="token punctuation">.</span>ltr
<span class="token punctuation">)</span>
</code></pre></div><h4 id="text-的-textdirection-属性什么时候可以缺省，为什么"><a href="#text-的-textdirection-属性什么时候可以缺省，为什么" class="header-anchor">#</a> Text 的 TextDirection 属性什么时候可以缺省，为什么</h4> <h4 id="text-如何使用外部字体"><a href="#text-如何使用外部字体" class="header-anchor">#</a> Text 如何使用外部字体</h4> <ol><li><p>添加字体至 $app/fonts/</p></li> <li><p>修改 pubspec.yaml 配置文件，关于配置文件的具体作用请往下翻阅</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">flutter</span><span class="token punctuation">:</span>
  <span class="token key atrule">fonts</span><span class="token punctuation">:</span>
    <span class="token punctuation">-</span> <span class="token key atrule">family</span><span class="token punctuation">:</span> xinxi
      <span class="token key atrule">fonts</span><span class="token punctuation">:</span>
        <span class="token punctuation">-</span> <span class="token key atrule">asset</span><span class="token punctuation">:</span> fonts/臺灣新細明體.ttf
</code></pre></div></li> <li><p>代码中引用字体</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token function">Text</span><span class="token punctuation">(</span>
    <span class="token string">'暮从碧山下'</span><span class="token punctuation">,</span>
    style<span class="token punctuation">:</span> <span class="token function">TextStyle</span><span class="token punctuation">(</span>
        fontSize<span class="token punctuation">:</span> <span class="token number">36</span><span class="token punctuation">,</span>
        fontFamily<span class="token punctuation">:</span> <span class="token string">'xinxi'</span><span class="token punctuation">,</span>
    <span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">,</span>
</code></pre></div></li> <li><p>无发热更新，重启应用生效</p></li></ol> <h4 id="text-如何从上往下排列，实现-writing-mode-vertical-rl-的效果"><a href="#text-如何从上往下排列，实现-writing-mode-vertical-rl-的效果" class="header-anchor">#</a> Text 如何从上往下排列，实现 <code>writing-mode: vertical-rl</code> 的效果</h4> <p>使用一个取巧的办法，即把字体父元素宽度设置为仅仅大于字体宽度，可以视为从上往下排列</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token function">Container</span><span class="token punctuation">(</span>
  width<span class="token punctuation">:</span> <span class="token number">48</span><span class="token punctuation">,</span>
  child<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span>
    <span class="token string">'照弹琴'</span><span class="token punctuation">,</span>
     style<span class="token punctuation">:</span> <span class="token function">TextStyle</span><span class="token punctuation">(</span>
       fontSize<span class="token punctuation">:</span> <span class="token number">36</span><span class="token punctuation">,</span>
     <span class="token punctuation">)</span>
  <span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span>
</code></pre></div><h4 id="如何统一设置-text-的字号字体和样式"><a href="#如何统一设置-text-的字号字体和样式" class="header-anchor">#</a> 如何统一设置 Text 的字号字体和样式</h4> <p>可以通过设置 <code>ThemeData</code> 设置一套主题，其中的 <code>textTheme</code> 控制字体的样式</p> <h3 id="container-widget"><a href="#container-widget" class="header-anchor">#</a> Container Widget</h3> <h4 id="样式"><a href="#样式" class="header-anchor">#</a> 样式</h4> <p><code>BoxDecoration</code> 可以设置 <code>margin</code>，<code>padding</code>, <code>border</code> 和 <code>color</code> (类似于 css 中的背景)等。与 css 类比如下</p> <div class="language- extra-class"><pre class="language-text"><code>// dart
Container( 
  width: 100,
  height: 100,
  margin: EdgeInsets.all(24),
  padding: EdgeInsets.only(top: 24),
  alignment: Alignment.center,
  decoration: BoxDecoration(
    color: const Colors.white,
    border: Border.all(
      color: Colors.blue,
      width: 1.0,
    ),
  ),
  child: MyWidget()
))


// css 
.container {
  width: 100px;
  height: 100px;
  margin: 24px;
  padding-top: 24px;
  text-align: center; 
  background-color: white;
  border: 1px solid blue;
}
</code></pre></div><h4 id="颜色"><a href="#颜色" class="header-anchor">#</a> 颜色</h4> <p>表示颜色的有两类 <code>Color</code> 与 <code>Colors</code>，颜色的值可以使用十六进制，RGB 或者常量来表示。</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token comment">// 黑色</span>
<span class="token function">Color</span><span class="token punctuation">(</span><span class="token number">0xff000000</span><span class="token punctuation">)</span>

<span class="token comment">// RGBO，类似于 css 中的 rgba</span>
Color<span class="token punctuation">.</span><span class="token function">fromRGBO</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">.3</span><span class="token punctuation">)</span>

<span class="token comment">// 红色，等同与 Colors.red[500]</span>
Colors<span class="token punctuation">.</span>red

<span class="token comment">// 深红</span>
Colors<span class="token punctuation">.</span>red<span class="token punctuation">[</span><span class="token number">900</span><span class="token punctuation">]</span>
</code></pre></div><h3 id="row-column-widget"><a href="#row-column-widget" class="header-anchor">#</a> Row &amp; Column Widget</h3> <p>Row 与 Column 是几乎一模一样的组件，除了方向。如果你使用过 CSS 的 flex 布局，会很快理解这两个组件，他们完全是 flexbox，只不过 <code>flex-direction</code> 不一样。</p> <p>如果两个组件在 HTML 中，那么他们的默认样式就如下所描述的 CSS 一般</p> <div class="language-css extra-class"><pre class="language-css"><code><span class="token selector">Row</span> <span class="token punctuation">{</span>
  <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
  <span class="token property">flex-direction</span><span class="token punctuation">:</span> row<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token selector">Column</span> <span class="token punctuation">{</span>
  <span class="token property">display</span><span class="token punctuation">:</span> flex<span class="token punctuation">;</span>
  <span class="token property">flex-direction</span><span class="token punctuation">:</span> column<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>flexbox 中有纵轴，横轴之分，Row/Column 自然也有这两个属性。自我感觉 flutter 更语义一些</p> <ul><li>Flutter: mainAxisAlignment/crossAxisAlignment</li> <li>CSS: justify-content/align-items</li></ul> <p>而且它们的属性值也是相同的</p> <ul><li><code>mainAxisAlignment.center</code> 👉 <code>justify-content: center</code></li> <li><code>mainAxisAlignment.start</code> 👉 <code>justify-content: flex-start</code></li> <li><code>mainAxisAlignment.end</code> 👉 <code>justify-content: flex-end</code></li> <li><code>mainAxisAlignment.spaceBetween</code> 👉 <code>justify-content: space-between</code></li> <li><code>mainAxisAlignment.spaceAround</code> 👉 <code>justify-content: space-around</code></li> <li><code>mainAxisAlignment.spaceEvenly</code> 👉 <code>justify-content: space-evenly</code></li></ul> <p>另外，在 css flex 中有一个 <code>flex-grow</code> 属性，可以对应到 flutter 中的 <code>Expanded</code></p> <h2 id="material-design"><a href="#material-design" class="header-anchor">#</a> Material Design</h2> <p>Meterial Design Guidelines</p> <blockquote><p>参考官方文档 https://material.io/design/</p></blockquote> <p>由于 <code>Scaffold</code> 组件在平时使用的频率较多，所以也特别介绍一下。但是这一块不是特别重要可以跳过。</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">class</span> <span class="token class-name">MyApp</span> <span class="token keyword">extends</span> <span class="token class-name">StatelessWidget</span> <span class="token punctuation">{</span>
  <span class="token metadata symbol">@override</span>
  Widget <span class="token function">build</span><span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">MaterialApp</span><span class="token punctuation">(</span>
        title<span class="token punctuation">:</span> <span class="token string">'Flutter Demo'</span><span class="token punctuation">,</span>
        theme<span class="token punctuation">:</span> <span class="token function">ThemeData</span><span class="token punctuation">(</span>
            primarySwatch<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>blue<span class="token punctuation">,</span>
            fontFamily<span class="token punctuation">:</span> <span class="token string">'xinxi'</span><span class="token punctuation">,</span>
            textTheme<span class="token punctuation">:</span> <span class="token function">TextTheme</span><span class="token punctuation">(</span>
              display2<span class="token punctuation">:</span> <span class="token function">TextStyle</span><span class="token punctuation">(</span>
                  fontSize<span class="token punctuation">:</span> <span class="token number">45.0</span><span class="token punctuation">,</span>
                  fontWeight<span class="token punctuation">:</span> FontWeight<span class="token punctuation">.</span>bold<span class="token punctuation">,</span>
                  color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>white<span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        home<span class="token punctuation">:</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">StatelessWidget</span> <span class="token punctuation">{</span>
  <span class="token metadata symbol">@override</span>
  Widget <span class="token function">build</span><span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">Scaffold</span><span class="token punctuation">(</span>
      appBar<span class="token punctuation">:</span> <span class="token function">AppBar</span><span class="token punctuation">(</span>
        title<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'诗词'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        actions<span class="token punctuation">:</span> <span class="token punctuation">[</span>
          <span class="token function">IconButton</span><span class="token punctuation">(</span>
            icon<span class="token punctuation">:</span> <span class="token function">Icon</span><span class="token punctuation">(</span>Icons<span class="token punctuation">.</span>share<span class="token punctuation">)</span><span class="token punctuation">,</span>
            color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>white<span class="token punctuation">,</span>
            onPressed<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
              <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'Press share'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token punctuation">,</span>
          <span class="token punctuation">)</span><span class="token punctuation">,</span>
          <span class="token function">IconButton</span><span class="token punctuation">(</span>
            icon<span class="token punctuation">:</span> <span class="token function">Icon</span><span class="token punctuation">(</span>Icons<span class="token punctuation">.</span>settings<span class="token punctuation">)</span><span class="token punctuation">,</span>
            color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>white<span class="token punctuation">,</span>
            onPressed<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
              <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'Press settings'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token punctuation">,</span>
          <span class="token punctuation">)</span>
        <span class="token punctuation">]</span><span class="token punctuation">,</span>
        leading<span class="token punctuation">:</span> <span class="token function">Builder</span><span class="token punctuation">(</span>
          builder<span class="token punctuation">:</span> <span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token function">IconButton</span><span class="token punctuation">(</span>
                icon<span class="token punctuation">:</span> <span class="token keyword">const</span> <span class="token function">Icon</span><span class="token punctuation">(</span>Icons<span class="token punctuation">.</span>menu<span class="token punctuation">)</span><span class="token punctuation">,</span>
                onPressed<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                  Scaffold<span class="token punctuation">.</span><span class="token function">of</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">openDrawer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token comment">// 抽屉，从侧栏打开，如 QQ</span>
      drawer<span class="token punctuation">:</span> <span class="token function">Drawer</span><span class="token punctuation">(</span>
        child<span class="token punctuation">:</span> <span class="token function">ListView</span><span class="token punctuation">(</span>
          padding<span class="token punctuation">:</span> EdgeInsets<span class="token punctuation">.</span>zero<span class="token punctuation">,</span>
          children<span class="token punctuation">:</span> <span class="token operator">&lt;</span>Widget<span class="token operator">&gt;</span><span class="token punctuation">[</span>
            <span class="token function">DrawerHeader</span><span class="token punctuation">(</span>
              child<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'诗酒趁年华'</span><span class="token punctuation">,</span> style<span class="token punctuation">:</span> Theme<span class="token punctuation">.</span><span class="token function">of</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">.</span>textTheme<span class="token punctuation">.</span>display2<span class="token punctuation">)</span><span class="token punctuation">,</span>
              decoration<span class="token punctuation">:</span> <span class="token function">BoxDecoration</span><span class="token punctuation">(</span>
                color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>blue<span class="token punctuation">,</span>
              <span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token function">ListTile</span><span class="token punctuation">(</span>
              title<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'我的诗词'</span><span class="token punctuation">,</span> style<span class="token punctuation">:</span> Theme<span class="token punctuation">.</span><span class="token function">of</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">.</span>textTheme<span class="token punctuation">.</span>display1<span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token function">ListTile</span><span class="token punctuation">(</span>
              title<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'我的收藏'</span><span class="token punctuation">,</span> style<span class="token punctuation">:</span> Theme<span class="token punctuation">.</span><span class="token function">of</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">.</span>textTheme<span class="token punctuation">.</span>display1<span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token punctuation">)</span><span class="token punctuation">,</span>
          <span class="token punctuation">]</span><span class="token punctuation">,</span>
        <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      body<span class="token punctuation">:</span> <span class="token function">Center</span><span class="token punctuation">(</span>
          child<span class="token punctuation">:</span> <span class="token function">Container</span><span class="token punctuation">(</span>
        child<span class="token punctuation">:</span> <span class="token function">Row</span><span class="token punctuation">(</span>
          mainAxisAlignment<span class="token punctuation">:</span> MainAxisAlignment<span class="token punctuation">.</span>center<span class="token punctuation">,</span>
          children<span class="token punctuation">:</span> <span class="token punctuation">[</span>
            <span class="token function">Container</span><span class="token punctuation">(</span>
              width<span class="token punctuation">:</span> <span class="token number">48</span><span class="token punctuation">,</span>
              child<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'照弹琴'</span><span class="token punctuation">,</span> style<span class="token punctuation">:</span> <span class="token function">TextStyle</span><span class="token punctuation">(</span>fontSize<span class="token punctuation">:</span> <span class="token number">36</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token punctuation">)</span>
          <span class="token punctuation">]</span><span class="token punctuation">,</span>
        <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
      floatingActionButton<span class="token punctuation">:</span> <span class="token function">FloatingActionButton</span><span class="token punctuation">(</span>
        onPressed<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
          <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'hello, world'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
        tooltip<span class="token punctuation">:</span> <span class="token string">'Increment'</span><span class="token punctuation">,</span>
        child<span class="token punctuation">:</span> <span class="token function">Icon</span><span class="token punctuation">(</span>Icons<span class="token punctuation">.</span>add<span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      bottomNavigationBar<span class="token punctuation">:</span> <span class="token function">BottomNavigationBar</span><span class="token punctuation">(</span>
        items<span class="token punctuation">:</span> <span class="token punctuation">[</span>
          <span class="token function">BottomNavigationBarItem</span><span class="token punctuation">(</span>
              icon<span class="token punctuation">:</span> <span class="token function">Icon</span><span class="token punctuation">(</span>Icons<span class="token punctuation">.</span>business<span class="token punctuation">)</span><span class="token punctuation">,</span> title<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'收藏'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
          <span class="token function">BottomNavigationBarItem</span><span class="token punctuation">(</span>icon<span class="token punctuation">:</span> <span class="token function">Icon</span><span class="token punctuation">(</span>Icons<span class="token punctuation">.</span>home<span class="token punctuation">)</span><span class="token punctuation">,</span> title<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'主页'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
          <span class="token function">BottomNavigationBarItem</span><span class="token punctuation">(</span>icon<span class="token punctuation">:</span> <span class="token function">Icon</span><span class="token punctuation">(</span>Icons<span class="token punctuation">.</span>school<span class="token punctuation">)</span><span class="token punctuation">,</span> title<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'诗词'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">]</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="appbar"><a href="#appbar" class="header-anchor">#</a> AppBar</h3> <h3 id="icon"><a href="#icon" class="header-anchor">#</a> Icon</h3> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token function">IconButton</span><span class="token punctuation">(</span>
  icon<span class="token punctuation">:</span> <span class="token function">Icon</span><span class="token punctuation">(</span>Icons<span class="token punctuation">.</span>share<span class="token punctuation">)</span><span class="token punctuation">,</span>
  color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>white<span class="token punctuation">,</span>
  tooltip<span class="token punctuation">:</span> <span class="token string">'分享到朋友圈'</span><span class="token punctuation">,</span>
  onPressed<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">print</span><span class="token punctuation">(</span><span class="token string">'Icon Share'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">,</span>
</code></pre></div><blockquote><p>至于更多图标参考 https://docs.flutter.io/flutter/material/Icons-class.html</p></blockquote> <h3 id="tabbar"><a href="#tabbar" class="header-anchor">#</a> TabBar</h3> <p><code>TabBar</code> 使用 <code>Tab</code>，<code>TabBarView</code> 以及 <code>TabController</code> 控制。</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">class</span> <span class="token class-name">MyTabbedPage</span> <span class="token keyword">extends</span> <span class="token class-name">StatefulWidget</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token function">MyTabbedPage</span><span class="token punctuation">(</span><span class="token punctuation">{</span> Key key <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token keyword">super</span><span class="token punctuation">(</span>key<span class="token punctuation">:</span> key<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token metadata symbol">@override</span>
  _MyTabbedPageState <span class="token function">createState</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token function">_MyTabbedPageState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// with 操作符代表一个 Mixin，在创建 TabController 时会用到</span>
<span class="token keyword">class</span> <span class="token class-name">_MyTabbedPageState</span> <span class="token keyword">extends</span> <span class="token class-name">State</span><span class="token operator">&lt;</span>MyTabbedPage<span class="token operator">&gt;</span> <span class="token keyword">with</span> SingleTickerProviderStateMixin <span class="token punctuation">{</span>
  <span class="token keyword">final</span> List<span class="token operator">&lt;</span>Tab<span class="token operator">&gt;</span> myTabs <span class="token operator">=</span> <span class="token operator">&lt;</span>Tab<span class="token operator">&gt;</span><span class="token punctuation">[</span>
    <span class="token function">Tab</span><span class="token punctuation">(</span>text<span class="token punctuation">:</span> <span class="token string">'LEFT'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token function">Tab</span><span class="token punctuation">(</span>text<span class="token punctuation">:</span> <span class="token string">'RIGHT'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">]</span><span class="token punctuation">;</span>

  TabController _tabController<span class="token punctuation">;</span>

  <span class="token metadata symbol">@override</span>
  <span class="token keyword">void</span> <span class="token function">initState</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">initState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    _tabController <span class="token operator">=</span> <span class="token function">TabController</span><span class="token punctuation">(</span>vsync<span class="token punctuation">:</span> <span class="token keyword">this</span><span class="token punctuation">,</span> length<span class="token punctuation">:</span> myTabs<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token metadata symbol">@override</span>
  <span class="token keyword">void</span> <span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  _tabController<span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>

  <span class="token metadata symbol">@override</span>
  Widget <span class="token function">build</span><span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">Scaffold</span><span class="token punctuation">(</span>
      appBar<span class="token punctuation">:</span> <span class="token function">AppBar</span><span class="token punctuation">(</span>
        <span class="token comment">// TabBar 由两部分组成，一部分为上边的 label，另一部分为下边的横线 indicator</span>
        bottom<span class="token punctuation">:</span> <span class="token function">TabBar</span><span class="token punctuation">(</span>
          controller<span class="token punctuation">:</span> _tabController<span class="token punctuation">,</span>
          tabs<span class="token punctuation">:</span> myTabs<span class="token punctuation">,</span>
          <span class="token comment">// tab 下的横线大小，label 表示尽可能小，tab 表示尽可能大</span>
          indicatorSize<span class="token punctuation">:</span> TabBarIndicatorSize<span class="token punctuation">.</span>label<span class="token punctuation">,</span>
        <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token comment">// tab容器，在指向特定tab时所呈现的内容</span>
      body<span class="token punctuation">:</span> <span class="token function">TabBarView</span><span class="token punctuation">(</span>
        controller<span class="token punctuation">:</span> _tabController<span class="token punctuation">,</span>
        children<span class="token punctuation">:</span> myTabs<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>Tab tab<span class="token punctuation">)</span> <span class="token punctuation">{</span>
          <span class="token keyword">return</span> <span class="token function">Center</span><span class="token punctuation">(</span>child<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span>tab<span class="token punctuation">.</span>text<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><blockquote><p>更多内容参考 https://docs.flutter.io/flutter/material/TabController-class.html</p></blockquote> <h2 id="布局实践"><a href="#布局实践" class="header-anchor">#</a> 布局实践</h2> <p>蜻蜓点水般介绍了两个组件，做两个常见的布局来测试你是否掌握了基本用法</p> <h3 id="垂直居中一个-300-300-固定宽高的组件"><a href="#垂直居中一个-300-300-固定宽高的组件" class="header-anchor">#</a> <strong>垂直居中一个 300 * 300 固定宽高的组件</strong></h3> <p>需要注意以下点</p> <ol><li><code>Center</code> 实现垂直居中</li> <li><code>Container</code> 置于 <code>Center</code> 下，宽与高才会生效</li></ol> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token function">Center</span><span class="token punctuation">(</span>
  child<span class="token punctuation">:</span> <span class="token function">Container</span><span class="token punctuation">(</span>
    width<span class="token punctuation">:</span> <span class="token number">300</span><span class="token punctuation">,</span>
    height<span class="token punctuation">:</span> <span class="token number">300</span><span class="token punctuation">,</span>
    color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>red<span class="token punctuation">,</span>
  <span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="垂直居中多行文字"><a href="#垂直居中多行文字" class="header-anchor">#</a> <strong>垂直居中多行文字</strong></h3> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token function">Center</span><span class="token punctuation">(</span>
  child<span class="token punctuation">:</span> <span class="token function">Column</span><span class="token punctuation">(</span>
    mainAxisSize<span class="token punctuation">:</span> MainAxisSize<span class="token punctuation">.</span>min<span class="token punctuation">,</span>
    crossAxisAlignment<span class="token punctuation">:</span> CrossAxisAlignment<span class="token punctuation">.</span>center<span class="token punctuation">,</span>
    children<span class="token punctuation">:</span> <span class="token punctuation">[</span>
      <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'hello, world'</span><span class="token punctuation">,</span> textDirection<span class="token punctuation">:</span> TextDirection<span class="token punctuation">.</span>ltr<span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'hello, world'</span><span class="token punctuation">,</span> textDirection<span class="token punctuation">:</span> TextDirection<span class="token punctuation">.</span>ltr<span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'hello, world'</span><span class="token punctuation">,</span> textDirection<span class="token punctuation">:</span> TextDirection<span class="token punctuation">.</span>ltr<span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="左侧固定-50px，中间自适应，右侧固定-50px"><a href="#左侧固定-50px，中间自适应，右侧固定-50px" class="header-anchor">#</a> 左侧固定 50px，中间自适应，右侧固定 50px</h3> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token function">Center</span><span class="token punctuation">(</span>
  child<span class="token punctuation">:</span> <span class="token function">Row</span><span class="token punctuation">(</span>
    textDirection<span class="token punctuation">:</span> TextDirection<span class="token punctuation">.</span>ltr<span class="token punctuation">,</span>
    children<span class="token punctuation">:</span> <span class="token punctuation">[</span>
      <span class="token function">Container</span><span class="token punctuation">(</span>
        width<span class="token punctuation">:</span> <span class="token number">80.0</span><span class="token punctuation">,</span>
        color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>red<span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token function">Expanded</span><span class="token punctuation">(</span>
        child<span class="token punctuation">:</span> <span class="token function">Container</span><span class="token punctuation">(</span>
          color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>white     
        <span class="token punctuation">)</span>    
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token function">Container</span><span class="token punctuation">(</span>
        width<span class="token punctuation">:</span> <span class="token number">80.0</span><span class="token punctuation">,</span>
        color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>blue<span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="平分5栏"><a href="#平分5栏" class="header-anchor">#</a> 平分5栏</h3> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token function">Center</span><span class="token punctuation">(</span>
  child<span class="token punctuation">:</span> <span class="token function">Row</span><span class="token punctuation">(</span>
    textDirection<span class="token punctuation">:</span> TextDirection<span class="token punctuation">.</span>ltr<span class="token punctuation">,</span>
    children<span class="token punctuation">:</span> <span class="token punctuation">[</span>
      <span class="token function">Expanded</span><span class="token punctuation">(</span>
        child<span class="token punctuation">:</span> <span class="token function">Container</span><span class="token punctuation">(</span>
          color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>white     
        <span class="token punctuation">)</span>    
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token function">Expanded</span><span class="token punctuation">(</span>
        child<span class="token punctuation">:</span> <span class="token function">Container</span><span class="token punctuation">(</span>
          color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>red
        <span class="token punctuation">)</span>    
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token function">Expanded</span><span class="token punctuation">(</span>
        child<span class="token punctuation">:</span> <span class="token function">Container</span><span class="token punctuation">(</span>
          color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>blue
        <span class="token punctuation">)</span>    
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token function">Expanded</span><span class="token punctuation">(</span>
          child<span class="token punctuation">:</span> <span class="token function">Container</span><span class="token punctuation">(</span>
            color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>red
          <span class="token punctuation">)</span>    
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token function">Expanded</span><span class="token punctuation">(</span>
          child<span class="token punctuation">:</span> <span class="token function">Container</span><span class="token punctuation">(</span>
            color<span class="token punctuation">:</span> Colors<span class="token punctuation">.</span>white     
          <span class="token punctuation">)</span>    
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="手势"><a href="#手势" class="header-anchor">#</a> 手势</h2> <p>html 和 flutter 有一个重大区别就是 html 是由 div 组成的，而 flutter 是由各种组件组成的。</p> <blockquote><p>即使在 html 中强调语义化标签，现在也有 web component 标准，但他们大多数都可以由 div 模拟而来，监听同样的 click 事件</p></blockquote> <p>手势当属移动端交互最多的事件，而所有手势事件都在 <code>GestureDetector</code> 组件上进行监听。当然，如果你使用流行的组件库，它们已经给你把时间封装到了组件。</p> <p>在 flutter 中有以下手势</p> <ul><li>Tap</li> <li>Double tap</li> <li>Long press</li> <li>Vertical drag</li> <li>Horizontal drag</li> <li>Pan</li></ul> <h2 id="状态"><a href="#状态" class="header-anchor">#</a> 状态</h2> <p>做了几个简单的布局之后，你会发现以上所有组件继承的都是 <code>StatelessWidget</code>，除此以外，还有另一种常用的组件 <code>StatefulWidget</code>。</p> <p>见词生义，两个组件的不同在于是否本身有状态需要维护。在 React 中，Component 也有 <code>Function Component</code> 和 <code>Class Component</code> 之分。如果你之前写过 React，你就会很快理解两者的区别。</p> <p>如何实现有状态的组件呢，有以下两点</p> <ol><li>有状态的组件需要实现两个类，<code>StatefulWidget</code> 和 <code>State</code> 的子类。</li> <li>使用 <code>setState</code> 更改状态</li></ol> <h3 id="生命周期"><a href="#生命周期" class="header-anchor">#</a> 生命周期</h3> <blockquote><p>说到生命周期，就有一个随之而来的问题，数据请求应该在哪一个生命周期</p></blockquote> <ul><li>initState</li> <li>didChangeDependencies</li> <li>build</li> <li>didUpdateState</li> <li>deactive</li> <li>dispose</li></ul> <h3 id="counter"><a href="#counter" class="header-anchor">#</a> Counter</h3> <p><code>Couter</code> 在状态管理的地位快比得上编程语言里的 <code>hello, world</code> 了。以下实现一个 <code>Counter</code> 组件。</p> <blockquote><p>flutter create 出来直接就是一个 <code>Counter</code> 组件。</p></blockquote> <p>先来介绍一下什么是 <code>Counter</code> 组件</p> <ul><li><code>Counter</code> 组件有一个按钮与一个数字组成</li> <li>每点击一次按钮，数字加1</li></ul> <p>做一个最小化描述 Counter 的代码，再加一点样式。</p> <ul><li>setState</li></ul> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'package:flutter/material.dart'</span><span class="token punctuation">;</span>

<span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token function">runApp</span><span class="token punctuation">(</span><span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">App</span> <span class="token keyword">extends</span> <span class="token class-name">StatelessWidget</span> <span class="token punctuation">{</span>
  Widget <span class="token function">build</span><span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">Counter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">Counter</span> <span class="token keyword">extends</span> <span class="token class-name">StatefulWidget</span> <span class="token punctuation">{</span>
  <span class="token metadata symbol">@override</span>
  _CounterState <span class="token function">createState</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token function">_CounterState</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">_CounterState</span> <span class="token keyword">extends</span> <span class="token class-name">State</span><span class="token operator">&lt;</span>Counter<span class="token operator">&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">// 状态都放在 State 的属性里边</span>
  int _count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>

  <span class="token metadata symbol">@override</span>
  Widget <span class="token function">build</span><span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 设置垂直居中</span>
    <span class="token keyword">return</span> <span class="token function">Center</span><span class="token punctuation">(</span>
      child<span class="token punctuation">:</span> <span class="token function">Column</span><span class="token punctuation">(</span>
        mainAxisSize<span class="token punctuation">:</span> MainAxisSize<span class="token punctuation">.</span>min<span class="token punctuation">,</span>
        crossAxisAlignment<span class="token punctuation">:</span> CrossAxisAlignment<span class="token punctuation">.</span>center<span class="token punctuation">,</span>
        children<span class="token punctuation">:</span> <span class="token punctuation">[</span>
          <span class="token comment">// +1 的按钮，被 GestureDetector 包裹监听事件</span>
          <span class="token function">GestureDetector</span><span class="token punctuation">(</span>
            onTap<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
              <span class="token comment">// 监听 Tap 事件，监听对 _count 进行自增</span>
              <span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                _count <span class="token operator">+=</span> <span class="token number">1</span><span class="token punctuation">;</span>
              <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token punctuation">,</span>
            child<span class="token punctuation">:</span> <span class="token function">Container</span><span class="token punctuation">(</span>
              child<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'点击 +1'</span><span class="token punctuation">,</span> textDirection<span class="token punctuation">:</span> TextDirection<span class="token punctuation">.</span>ltr<span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token punctuation">)</span><span class="token punctuation">,</span>
          <span class="token punctuation">)</span><span class="token punctuation">,</span>
          <span class="token function">Text</span><span class="token punctuation">(</span>_count<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> textDirection<span class="token punctuation">:</span> TextDirection<span class="token punctuation">.</span>ltr<span class="token punctuation">)</span>
        <span class="token punctuation">]</span>
      <span class="token punctuation">)</span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="状态管理方案"><a href="#状态管理方案" class="header-anchor">#</a> 状态管理方案</h3> <ul><li>Bloc</li> <li>redux</li></ul> <h3 id="valuenotifier"><a href="#valuenotifier" class="header-anchor">#</a> ValueNotifier</h3> <h2 id="调试"><a href="#调试" class="header-anchor">#</a> 调试</h2> <p>通过以上学习布局，你时时需要查看组件的位置，大小，以及嵌套关系。通过以上学习组件状态管理，你需要时时打印数据，查看数据流向，甚至打断点</p> <p>flutter 的调试如同前端一样分为两大块，UI 以及 Data。以下介绍 flutter 的调试</p> <h3 id="如何像-devtool-inspector-一样定位元素"><a href="#如何像-devtool-inspector-一样定位元素" class="header-anchor">#</a> 如何像 Devtool Inspector 一样定位元素</h3> <h3 id="如何打印数据至控制台"><a href="#如何打印数据至控制台" class="header-anchor">#</a> 如何打印数据至控制台</h3> <blockquote><p>你用的最多的调试手段是什么?
print</p></blockquote> <p>打印数据到控制台是最简单，最直接的方法。在 flutter 中</p> <h2 id="路由"><a href="#路由" class="header-anchor">#</a> 路由</h2> <p>这里先回顾一下前端的路由是如何控制的？</p> <p>前端路由通过 <code>history API</code> 控制跳转，在 flutter 中使用 <code>Navigator</code> 跳转。</p> <h3 id="navigator"><a href="#navigator" class="header-anchor">#</a> Navigator</h3> <p>正如 <code>history API</code> 一样，<code>Navigator</code> 使用 <code>push</code> 跳转路由，使用 <code>pop</code> 进行返回。</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token comment">// 跳转路由</span>
Navigator<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>
  context<span class="token punctuation">,</span>
  <span class="token comment">// 一般使用 MaterialPageRoute 进行路由控制，当然你也可以自定义路由</span>
  <span class="token function">MaterialPageRoute</span><span class="token punctuation">(</span>builder<span class="token punctuation">:</span> <span class="token punctuation">(</span>context<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token function">SecondRoute</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// 返回上一级</span>
Navigator<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>以下是路由跳转的示例</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'package:flutter/material.dart'</span><span class="token punctuation">;</span>

<span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">runApp</span><span class="token punctuation">(</span><span class="token function">MaterialApp</span><span class="token punctuation">(</span>
    title<span class="token punctuation">:</span> <span class="token string">'Navigation Basics'</span><span class="token punctuation">,</span>
    home<span class="token punctuation">:</span> <span class="token function">FirstRoute</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">FirstRoute</span> <span class="token keyword">extends</span> <span class="token class-name">StatelessWidget</span> <span class="token punctuation">{</span>
  <span class="token metadata symbol">@override</span>
  Widget <span class="token function">build</span><span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">Scaffold</span><span class="token punctuation">(</span>
      appBar<span class="token punctuation">:</span> <span class="token function">AppBar</span><span class="token punctuation">(</span>
        title<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'First Route'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      body<span class="token punctuation">:</span> <span class="token function">Center</span><span class="token punctuation">(</span>
        child<span class="token punctuation">:</span> <span class="token function">RaisedButton</span><span class="token punctuation">(</span>
          child<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'Open route'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
          onPressed<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            Navigator<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>
              context<span class="token punctuation">,</span>
              <span class="token function">MaterialPageRoute</span><span class="token punctuation">(</span>builder<span class="token punctuation">:</span> <span class="token punctuation">(</span>context<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token function">SecondRoute</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">SecondRoute</span> <span class="token keyword">extends</span> <span class="token class-name">StatelessWidget</span> <span class="token punctuation">{</span>
  <span class="token metadata symbol">@override</span>
  Widget <span class="token function">build</span><span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">Scaffold</span><span class="token punctuation">(</span>
      appBar<span class="token punctuation">:</span> <span class="token function">AppBar</span><span class="token punctuation">(</span>
        title<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">&quot;Second Route&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      body<span class="token punctuation">:</span> <span class="token function">Center</span><span class="token punctuation">(</span>
        child<span class="token punctuation">:</span> <span class="token function">RaisedButton</span><span class="token punctuation">(</span>
          onPressed<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            Navigator<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token punctuation">}</span><span class="token punctuation">,</span>
          child<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'Go back!'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="路由传值"><a href="#路由传值" class="header-anchor">#</a> 路由传值</h3> <p>在前端中，路由可以通过 <code>querystring</code> 或者 <code>pushState</code> 进行参数传递，那么在 <code>flutter</code> 中如何进行路由传值呢。</p> <p><strong>在 flutter 中可以在跳转路由的 builder 函数中，把将要传递的值作为组件的参数进行传递。</strong></p> <div class="language-dart extra-class"><pre class="language-dart"><code>Navigator<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>
  context<span class="token punctuation">,</span>
  <span class="token function">MaterialPageRoute</span><span class="token punctuation">(</span>builder<span class="token punctuation">:</span> <span class="token punctuation">(</span>context<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token function">SecondRoute</span><span class="token punctuation">(</span>props<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="命名路由-named-routes"><a href="#命名路由-named-routes" class="header-anchor">#</a> 命名路由 (Named Routes)</h3> <p>在 SPA 应用中会使用，路径以及组件的对应表来管理路由，伪代码如下</p> <div class="language-javascript extra-class"><pre class="language-javascript"><code><span class="token keyword">const</span> routes <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token string">'/admin'</span><span class="token operator">:</span> Admin<span class="token punctuation">,</span>
  <span class="token string">'/user'</span><span class="token operator">:</span> User
<span class="token punctuation">}</span>
</code></pre></div><p>在 flutter 中，可以在 MaterialApp 声明一个路径组件对应表，而路径即 Named Routes。</p> <p>在页面间进行路由跳转时可以直接使用路径名称 <code>Navigator.pushNamed(context, '/user')</code>。</p> <p>以下是一个命名路由的示例，来自官方。</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'package:flutter/material.dart'</span><span class="token punctuation">;</span>

<span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">runApp</span><span class="token punctuation">(</span><span class="token function">MaterialApp</span><span class="token punctuation">(</span>
    title<span class="token punctuation">:</span> <span class="token string">'Named Routes Demo'</span><span class="token punctuation">,</span>
    initialRoute<span class="token punctuation">:</span> <span class="token string">'/'</span><span class="token punctuation">,</span>
    routes<span class="token punctuation">:</span> <span class="token punctuation">{</span>
      <span class="token string">'/'</span><span class="token punctuation">:</span> <span class="token punctuation">(</span>context<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token function">FirstScreen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token string">'/second'</span><span class="token punctuation">:</span> <span class="token punctuation">(</span>context<span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token function">SecondScreen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">FirstScreen</span> <span class="token keyword">extends</span> <span class="token class-name">StatelessWidget</span> <span class="token punctuation">{</span>
  <span class="token metadata symbol">@override</span>
  Widget <span class="token function">build</span><span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">Scaffold</span><span class="token punctuation">(</span>
      appBar<span class="token punctuation">:</span> <span class="token function">AppBar</span><span class="token punctuation">(</span>
        title<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'First Screen'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      body<span class="token punctuation">:</span> <span class="token function">Center</span><span class="token punctuation">(</span>
        child<span class="token punctuation">:</span> <span class="token function">RaisedButton</span><span class="token punctuation">(</span>
          child<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'Launch screen'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
          onPressed<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            Navigator<span class="token punctuation">.</span><span class="token function">pushNamed</span><span class="token punctuation">(</span>context<span class="token punctuation">,</span> <span class="token string">'/second'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">SecondScreen</span> <span class="token keyword">extends</span> <span class="token class-name">StatelessWidget</span> <span class="token punctuation">{</span>
  <span class="token metadata symbol">@override</span>
  Widget <span class="token function">build</span><span class="token punctuation">(</span>BuildContext context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">Scaffold</span><span class="token punctuation">(</span>
      appBar<span class="token punctuation">:</span> <span class="token function">AppBar</span><span class="token punctuation">(</span>
        title<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">&quot;Second Screen&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
      body<span class="token punctuation">:</span> <span class="token function">Center</span><span class="token punctuation">(</span>
        child<span class="token punctuation">:</span> <span class="token function">RaisedButton</span><span class="token punctuation">(</span>
          onPressed<span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            Navigator<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token punctuation">}</span><span class="token punctuation">,</span>
          child<span class="token punctuation">:</span> <span class="token function">Text</span><span class="token punctuation">(</span><span class="token string">'Go back!'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">)</span><span class="token punctuation">,</span>
      <span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><blockquote><p>参考官方文档 <a href="https://flutter.dev/docs/cookbook/navigation/named-routes" target="_blank" rel="noopener noreferrer">Navigate with named routes<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <h3 id="路由管理"><a href="#路由管理" class="header-anchor">#</a> 路由管理</h3> <p>在一个 <code>flutter</code> 应用中可以使用命名路由进行管理。也可以使用 <a href="https://github.com/theyakka/fluro" target="_blank" rel="noopener noreferrer">fluro<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> 统一管理路由。</p> <h2 id="包管理"><a href="#包管理" class="header-anchor">#</a> 包管理</h2> <p>现在我们已经掌握了组件，路由，状态的用法，已经可以写一个相对简单的应用了。但我们现在仅仅只在单文件中进行操作，且没有引入额外的库。而且，你肯定发现了文件首行的代码</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'package:flutter/material.dart'</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="引入库-importing-a-library"><a href="#引入库-importing-a-library" class="header-anchor">#</a> 引入库 (Importing a Library)</h3> <p>在 <code>Dart</code> 中，引入官方库使用 <code>dart:&lt;library&gt;</code>，比如</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'dart:convert'</span><span class="token punctuation">;</span>
</code></pre></div><p>而对于其它非Dart官方库，采用 <code>package:&lt;package&gt;/&lt;library&gt;.dart</code>，比如 flutter</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'package:flutter/material.dart'</span><span class="token punctuation">;</span>
</code></pre></div><p>更多三方库可以在 https://pub.dartlang.org/flutter 上查找</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'package:url_launcher/url_launcher.dart'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token string">'package:graphql_flutter/graphql_flutter.dart'</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>在 <code>Dart</code> 中有很烦的一点是你当你使用某个 API 的时候，你不知道它出自与哪个库去，这时候你可以在引入库的时候使用 <code>json</code> 显式标明。</strong></p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'dart:convert'</span> show json<span class="token punctuation">;</span>
</code></pre></div><p>在使用第三方库之前还需要引用依赖，并安装，进行包管理</p> <h3 id="如何引入另一个文件"><a href="#如何引入另一个文件" class="header-anchor">#</a> 如何引入另一个文件</h3> <p>以上引入的都是第三方库或者官方的一些库，如果需要引入本地路径下的文件呢。</p> <blockquote><p>参考 <a href="https://stackoverflow.com/questions/12951989/how-to-reference-another-file-in-dart?utm_medium=organic&amp;utm_source=google_rich_qa&amp;utm_campaign=google_rich_qa" target="_blank" rel="noopener noreferrer">How to reference another file in Dart?<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <h3 id="依赖"><a href="#依赖" class="header-anchor">#</a> 依赖</h3> <p>在学习 flutter 的包管理工具之前，先回顾一下 node 的包管理工具 <code>npm</code>。</p> <p>npm 使用 <code>package.json</code> 管理包，使用 <code>package-lock.json</code> 锁定包的版本，避免开发环境与生产环境的不一致。</p> <p>而在 flutter 中，也有同样功能的两个文件。他们的版本号也同样遵守 <a href="https://semver.org/spec/v2.0.0-rc.1.html" target="_blank" rel="noopener noreferrer">Semantic Versioning<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <ul><li><code>pubspec.yaml</code> 👉 <code>package.json</code></li> <li><code>pubspec.lock</code> 👉 <code>package-lock.json</code></li></ul> <p>在使用第三方库之前，还需要 <strong>手动编辑</strong> <code>pubspec.yaml</code> 添加依赖</p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">dependencies</span><span class="token punctuation">:</span>
  <span class="token key atrule">url_launcher</span><span class="token punctuation">:</span> ^5.0.2
</code></pre></div><p>然后进行安装</p> <div class="language-shell extra-class"><pre class="language-shell"><code>flutter packages get
</code></pre></div><h2 id="permission-api"><a href="#permission-api" class="header-anchor">#</a> Permission API</h2> <p>PACKAGE_USAGE_STATS</p> <div class="language-xml extra-class"><pre class="language-xml"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uses-permission</span>
  <span class="token attr-name"><span class="token namespace">android:</span>name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>android.permission.PACKAGE_USAGE_STATS<span class="token punctuation">&quot;</span></span>
  <span class="token attr-name"><span class="token namespace">tools:</span>ignore</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>ProtectedPermissions<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
</code></pre></div><h2 id="http-请求"><a href="#http-请求" class="header-anchor">#</a> http 请求</h2> <p>flutter 作为移动端框架，更多时候需要服务器的支持，一个 http 请求库此时应是登场的时候了。</p> <p>你对一个 http 请求库的了解程度取决于你对 <code>http protocol</code> 的了解程度，需要使用时直接查找文档即可。这里仅仅列出它如何发送最为常见的 <code>GET</code> 和 <code>POST</code> 请求。</p> <p><code>http</code> 请求属于异步操作，返回一个 <code>Future</code>。如果你对此概念感到陌生，你需要往上翻，复习一下 <code>Future</code> 的用法。</p> <p>这里介绍一个国人写的请求库 <code>dio</code>，为了能够使用它，这里首先介绍一下包管理器。</p> <p>编辑 <code>pubspec.yaml</code>，添加依赖库 <code>dio</code></p> <div class="language-yaml extra-class"><pre class="language-yaml"><code><span class="token key atrule">dependencies</span><span class="token punctuation">:</span>
  <span class="token key atrule">flutter</span><span class="token punctuation">:</span>
    <span class="token key atrule">sdk</span><span class="token punctuation">:</span> flutter
  <span class="token key atrule">dio</span><span class="token punctuation">:</span> ^2.1.0
</code></pre></div><p>接下来 <code>flutter packages get</code> 装包，重启，完成了 dio 的安装。</p> <p>在需要的文件中，引入它</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'package:dio/dio.dart'</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="dio"><a href="#dio" class="header-anchor">#</a> Dio</h3> <div class="language-dart extra-class"><pre class="language-dart"><code>Response response<span class="token punctuation">;</span>
Dio dio <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Dio</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

response <span class="token operator">=</span> <span class="token keyword">await</span> dio<span class="token punctuation">.</span><span class="token keyword">get</span><span class="token punctuation">(</span><span class="token string">'/'</span><span class="token punctuation">)</span>
response <span class="token operator">=</span> <span class="token keyword">await</span> dio<span class="token punctuation">.</span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string">'https://shici.xiange.tech/graphql'</span><span class="token punctuation">,</span> data<span class="token punctuation">:</span> <span class="token punctuation">{</span> <span class="token string">'query'</span><span class="token punctuation">:</span> <span class="token string">'{ping}'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// {&quot;data&quot;:{&quot;ping&quot;:&quot;pong&quot;}}</span>
<span class="token function">print</span><span class="token punctuation">(</span>response<span class="token punctuation">)</span>

<span class="token comment">// 'pong'</span>
<span class="token function">print</span><span class="token punctuation">(</span>response<span class="token punctuation">.</span>data<span class="token punctuation">[</span><span class="token string">'data'</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string">'ping'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="json"><a href="#json" class="header-anchor">#</a> JSON</h3> <p>dart 的 JSON 处理实在是丧心病狂了，相当怀念 <code>js</code>，不过也没办法，毕竟 JSON 的全称是 <code>JavaScript Object Notation</code>。</p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'dart:convert'</span> show json<span class="token punctuation">;</span>

<span class="token keyword">var</span> s <span class="token operator">=</span> <span class="token string">'{&quot;name&quot;: &quot;shanyue&quot;}'</span>

Map<span class="token operator">&lt;</span>String<span class="token punctuation">,</span> <span class="token keyword">dynamic</span><span class="token operator">&gt;</span> user <span class="token operator">=</span> json<span class="token punctuation">.</span><span class="token function">decode</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">print</span><span class="token punctuation">(</span>user<span class="token punctuation">[</span><span class="token string">'name'</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
</code></pre></div><blockquote><p>其实作为以前写 python 和 javascript 的我表示完全无所谓...</p></blockquote> <h3 id="streambuilder-futurebuilder"><a href="#streambuilder-futurebuilder" class="header-anchor">#</a> StreamBuilder &amp;&amp; FutureBuilder</h3> <p>想象一个经典场景，当加载数据时显示加载状态，加载完成后正常显示数据。按照以前的思路，使用 jsx 做了伪代码如下</p> <div class="language-jsx extra-class"><pre class="language-jsx"><code><span class="token punctuation">{</span>
  loading <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Loading</span></span> <span class="token punctuation">/&gt;</span></span> <span class="token operator">:</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Page</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token punctuation">}</span>
</code></pre></div><p>不过在 flutter 中可以使用 <code>FutureBuilder</code> 来进行实现</p> <h3 id="memoization"><a href="#memoization" class="header-anchor">#</a> Memoization</h3> <h2 id="存储"><a href="#存储" class="header-anchor">#</a> 存储</h2> <h3 id="key-value-存储"><a href="#key-value-存储" class="header-anchor">#</a> key/value 存储</h3> <p><strong>package -&gt; <code>shared_preferences</code></strong></p> <div class="language-dart extra-class"><pre class="language-dart"><code><span class="token keyword">import</span> <span class="token string">'package:shared_preferences/shared_preferences.dart'</span><span class="token punctuation">;</span>

SharedPreferences prefs <span class="token operator">=</span> <span class="token keyword">await</span> SharedPreferences<span class="token punctuation">.</span><span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
prefs<span class="token punctuation">.</span><span class="token function">setInt</span><span class="token punctuation">(</span><span class="token string">'count'</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">final</span> count <span class="token operator">=</span> prefs<span class="token punctuation">.</span><span class="token function">getInt</span><span class="token punctuation">(</span><span class="token string">'counter'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="database"><a href="#database" class="header-anchor">#</a> database</h3> <p><strong>package -&gt; <code>sqflite</code></strong></p> <h2 id="参考"><a href="#参考" class="header-anchor">#</a> 参考</h2> <ul><li><a href="https://fireship.io/lessons/flutter-widget-positioning-guide/" target="_blank" rel="noopener noreferrer">flutter 组件定位指南<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="https://flutter.dev/docs/cookbook" target="_blank" rel="noopener noreferrer">Flutter Cookbook<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="https://hackr.io/blog/react-native-vs-flutter" target="_blank" rel="noopener noreferrer">react native VS flutter<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul></div> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">7/20/2020, 2:09:44 AM</span></div></footer> <!----> </main></div><div class="global-ui"></div></div>
    <script src="/assets/js/app.cb35c8f6.js" defer></script><script src="/assets/js/2.063846a6.js" defer></script><script src="/assets/js/4.1ffb4609.js" defer></script><script src="/assets/js/698.200cc84f.js" defer></script>
  </body>
</html>
